TypeDrop
2026-04-10 Challenge
2026-04-10
Easy
Typed Task Queue Scheduler
You're building the background job runner for a productivity app. Raw task definitions arrive from a local database as unknown blobs; your scheduler must validate them, sort them by priority and deadline, and return a fully typed execution plan — with zero `any`.
Goals
- Define PRIORITY_WEIGHTS using the `satisfies` operator so every Priority key is present and all values are numbers.
- Implement `validateTask` to safely narrow `unknown` → `Result<Task, ValidationError>`, returning the first validation error found.
- Implement `computeRank` to produce a branded `ScheduleRank` using the priority weight formula.
- Implement `scheduleTasks` to validate, rank, sort, re-number, and aggregate all valid tasks into a typed `ExecutionPlan`.
challenge.ts
// Key types and main function signature
export type Priority = "low" | "medium" | "high";
export interface Task {
id: string;
title: string;
priority: Priority;
deadline: string; // ISO-8601 e.g. "2026-04-15"
estimatedMinutes: number; // positive integer
}
export type Result<T, E> =
| { ok: true; value: T }
| { ok: false; error: E };
export type ValidationError =
| { kind: "missing_field"; field: string }
| { kind: "invalid_type"; field: string; expected: string }
| { kind: "invalid_value"; field: string; message: string };
export type ScheduleRank = number & { readonly __brand: "ScheduleRank" };
export interface ExecutionPlan {
scheduled: { task: Task; rank: ScheduleRank }[];
totalEstimatedMinutes: number;
generatedAt: string;
}
// Entry point — validate, rank, sort, and plan
export function scheduleTasks(
rawTasks: unknown[],
now?: string
): ExecutionPlan { /* TODO */ }
Hints (click to reveal)
Hints
- For `validateTask`, check `typeof raw === 'object' && raw !== null` first, then use `'field' in raw` guards to safely access each property.
- The `satisfies` operator lets you keep a concrete literal type while still checking the shape — put it right after the object literal: `{ ... } satisfies Record<Priority, number>`.
- To brand a plain number as `ScheduleRank`, the one allowed cast site is the return of `computeRank`: `return computedNumber as ScheduleRank`.
Useful resources
Or clone locally
git clone -b challenge/2026-04-10 https://github.com/niltonheck/typedrop.git