TypeDrop

2026-03-19 Challenge

2026-03-19 Easy

Typed Task Priority Queue

You're building the task management feature for a lightweight project tool. Users submit raw task entries, and your engine must validate them, assign a computed urgency tier, and serve them back in priority order — all with zero `any`.

Goals

  • Implement `computeUrgency` to map priority + days-until-due to the correct UrgencyTier using the provided matrix.
  • Implement `validateTask` to narrow `unknown` input field-by-field and return a fully typed `Result<Task, ValidationError>` — no `as`, no `any`.
  • Implement `buildPriorityQueue` to collect all errors across inputs and return valid tasks sorted by urgencyTier DESC then dueDate ASC.
  • Implement `filterByStatus` and `groupByUrgency`, ensuring `groupByUrgency` always returns all five tier keys typed as `Record<UrgencyTier, Task[]>`.
challenge.ts

// Key types & main function signatures:

type RawPriority = "low" | "medium" | "high";
type UrgencyTier = 1 | 2 | 3 | 4 | 5;
type TaskStatus  = "pending" | "in-progress" | "done";

interface Task {
  id: string;
  title: string;
  priority: RawPriority;
  dueDate: Date;
  status: TaskStatus;
  tags: string[];
  urgencyTier: UrgencyTier; // computed from priority + dueDate
}

type Ok<T>       = { ok: true;  value: T };
type Err<E>      = { ok: false; error: E };
type Result<T,E> = Ok<T> | Err<E>;

// Validate one unknown input → typed Task or a ValidationError
function validateTask(input: unknown): Result<Task, ValidationError> { ... }

// Validate all inputs, collect errors, return sorted Task[]
function buildPriorityQueue(rawInputs: unknown[]): {
  tasks:  Task[];
  errors: Array<{ index: number; error: ValidationError }>;
} { ... }
Hints (click to reveal)

Hints

  • For `unknown` narrowing, check `typeof field === 'string'` and membership in a const array (e.g. `const PRIORITIES = ['low','medium','high'] as const`) — TypeScript will narrow the type for you.
  • A `Result<T,E>` discriminated union is narrowed by checking `.ok`: inside `if (result.ok)` the value is `Ok<T>`, otherwise `Err<E>`.
  • To satisfy `Record<UrgencyTier, Task[]>`, initialise the object with all five keys before pushing into it — e.g. `{ 1: [], 2: [], 3: [], 4: [], 5: [] }`.

Or clone locally

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