TypeDrop

2026-09-01 Challenge

2026-09-01 Medium

Typed Job Queue with Priority Scheduling & Retry Budgets

You're building the background-job engine for a SaaS platform. Jobs arrive with different priorities and payload shapes, each worker declares which job kinds it handles, and failed jobs must be retried up to a per-kind budget — all with the compiler catching mismatches before they reach production.

Goals

  • Define an exhaustive discriminated union `Job` with three variants, each carrying a `priority` and kind-specific payload fields.
  • Implement the `Worker<K>` generic interface so `execute` only receives jobs whose `kind` matches `K`, enforced via `Extract<Job, { kind: K }>`.
  • Implement `createQueue` so `runAll` processes jobs in priority order, dispatches to the correct registered worker, and retries failures up to the per-kind budget.
  • Return a correctly tallied `QueueSummary` distinguishing succeeded, failed (budget exhausted), and skipped (no worker registered) jobs.
challenge.ts
export type Job = EmailJob | ResizeJob | ReportJob;

export type RetryBudget = Record<Job["kind"], number>;

export interface Worker<K extends Job["kind"]> {
  handles: K[];
  execute(job: Extract<Job, { kind: K }>): Promise<void>;
}

export type QueueSummary = {
  succeeded: number;
  failed: number;
  skipped: number;
};

export function createQueue(budget: RetryBudget): {
  enqueue(job: Job): void;
  registerWorker<K extends Job["kind"]>(worker: Worker<K>): void;
  runAll(): Promise<QueueSummary>;
} {
  throw new Error("Not implemented");
}
Hints (click to reveal)

Hints

  • The `Extract<Job, { kind: K }>` utility type narrows the full `Job` union down to only the variant(s) where `kind` matches `K` — use it in the `Worker` interface's `execute` signature.
  • Inside `runAll`, you'll need to narrow a `Job` to the specific variant before passing it to a worker — a `kind` check in an `if`/`switch` is enough for TypeScript to infer the narrowed type.
  • Model the internal worker registry as a `Map` or a `Partial<Record<Job['kind'], Worker<Job['kind']>>>` — just make sure you handle the 'no worker found' case without a non-null assertion.

Or clone locally

git clone -b challenge/2026-09-01 https://github.com/niltonheck/typedrop.git