TypeDrop

2026-03-24 Challenge

2026-03-24 Medium

Typed Paginated API Response Aggregator

You're building the data-sync layer for a dashboard that pulls records from a paginated REST API. The fetcher must handle typed pages, collect results across all pages with a concurrency limit, and surface either a fully aggregated dataset or a structured `Result<T, E>` error — with zero `any`.

Goals

  • Implement the `ok` and `err` Result constructors and use them throughout without type assertions.
  • Fetch page 1 first to discover `totalPages`, then fetch remaining pages in concurrency-limited batches.
  • Respect the `failFast` flag — abort with `Err<AggregateError>` on the first failure, or accumulate errors into `failedPages` when lenient.
  • Implement `formatFetchError` with an exhaustive discriminated-union switch so TypeScript catches any missing case.
challenge.ts
// Core types at a glance

type ApiRecord<T> = { id: string; createdAt: string; payload: T };
type Page<T>      = { page: number; totalPages: number; items: ApiRecord<T>[] };

type FetchError =
  | { kind: "network"; message: string; page: number }
  | { kind: "timeout"; page: number; afterMs: number }
  | { kind: "parse";   page: number; raw: string }
  | { kind: "unknown"; page: number; cause: unknown };

type PageFetcher<T> = (page: number) => Promise<Result<Page<T>, FetchError>>;

// Main function to implement:
async function aggregatePages<T>(
  fetchPage: PageFetcher<T>,
  config: { concurrency: number; failFast: boolean }
): Promise<Result<AggregateSuccess<T>, AggregateError>> { ... }
Hints (click to reveal)

Hints

  • Batch an array of page numbers into chunks of size `concurrency` and `await Promise.all(chunk.map(...))` each batch sequentially.
  • The `Result<T, E>` discriminant is `ok: true/false` — narrow it with an `if (result.ok)` check, never with `as`.
  • For exhaustive matching in `formatFetchError`, add a `default` branch that assigns to a `never` variable to get a compile-time safety net.

Or clone locally

git clone -b challenge/2026-03-24 https://github.com/niltonheck/typedrop.git