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.
Useful resources
Or clone locally
git clone -b challenge/2026-09-01 https://github.com/niltonheck/typedrop.git