TypeDrop

2026-08-02 Challenge

2026-08-02 Easy

Typed GroupBy & Aggregation Pipeline

You're building the reporting layer for a small e-commerce analytics dashboard. Raw order records arrive as a flat array and must be grouped by an arbitrary key, then reduced into a typed summary — all without losing type information or reaching for `any`.

Goals

  • Implement a generic `groupBy` that groups any array by a string key function, preserving item order.
  • Implement `summariseGroup` that reduces an array of Orders into a fully-typed `OrderSummary`, handling the empty-array edge case.
  • Define the `StringKeys<T>` helper type that resolves to only the keys of `T` whose value type is `string`.
  • Implement `buildReport` using `StringKeys<Order>` to reject non-string keys at compile time, composing `groupBy` and `summariseGroup` internally.
challenge.ts
interface Order {
  id: string;
  customerId: string;
  region: "NA" | "EU" | "APAC";
  status: "pending" | "fulfilled" | "cancelled";
  amountUsd: number;
  itemCount: number;
}

interface OrderSummary {
  count: number;
  totalAmountUsd: number;
  averageAmountUsd: number;
  totalItemCount: number;
  orderIds: string[];
}

// Helper type — your job to define this:
type StringKeys<T> = never; // TODO

// The three functions you must implement:
function groupBy<T>(items: T[], keyFn: (item: T) => string): Record<string, T[]>;

function summariseGroup(orders: Order[]): OrderSummary;

function buildReport<K extends StringKeys<Order>>(
  orders: Order[],
  groupKey: K        // only string-valued keys of Order are accepted
): Record<string, OrderSummary>;
Hints (click to reveal)

Hints

  • For `StringKeys<T>`, think about mapped types combined with `keyof` — you want to keep only those keys `K` where `T[K]` extends `string`.
  • In `summariseGroup`, a single `reduce` pass can accumulate all fields at once — no need for multiple iterations.
  • `buildReport` can call `groupBy(orders, o => o[groupKey])` — TypeScript will accept this once `K extends StringKeys<Order>` guarantees the value is a string.

Or clone locally

git clone -b challenge/2026-08-02 https://github.com/niltonheck/typedrop.git