TypeDrop
2026-07-15 Challenge
2026-07-15
Easy
Typed CSV Row Parser & Aggregator
You're building the data-import feature for a budgeting app. Raw CSV rows arrive as plain strings; your module must parse and validate each row into a strongly-typed `Transaction` record, collect typed parse errors, and then aggregate the valid rows into a per-category `SpendingSummary` — with zero `any`.
Goals
- Define `ParseResult<T>` as a generic discriminated union with `ok: true` and `ok: false` variants.
- Implement `parseTransactionRow` that validates all five rules and returns the correct `ParseResult<Transaction>` variant.
- Implement `parseAll` that separates valid transactions from structured error entries in a single pass.
- Define `SpendingSummary` as a mapped type over `Category` and implement `summariseByCategory` so every category key is always present in the output.
challenge.ts
// Key types you must define and implement:
export type Category = "food" | "transport" | "utilities" | "entertainment" | "other";
export interface Transaction {
date: string; // YYYY-MM-DD
amount: number; // positive, ≤ 2 decimal places
category: Category;
description: string; // non-empty
}
// Discriminated union — you define this:
export type ParseResult<T> = /* TODO */ never;
// Mapped type over Category — you define this:
export type SpendingSummary = /* TODO */ never;
// Functions you must implement:
export function parseTransactionRow(row: string): ParseResult<Transaction>;
export function parseAll(rows: string[]): ParseAllResult;
export function summariseByCategory(transactions: Transaction[]): SpendingSummary;
Hints (click to reveal)
Hints
- For `ParseResult<T>`, a discriminated union uses a shared literal field (like `ok`) as the discriminant — TypeScript can then narrow the type in an `if` block.
- For `SpendingSummary`, `{ [K in Category]: { total: number; count: number } }` ensures every category key is always present — seed them all to zero before iterating.
- To validate `category`, build a `Set` or `const` array of all valid `Category` values and write a type-guard function that returns `value is Category`.
Useful resources
Or clone locally
git clone -b challenge/2026-07-15 https://github.com/niltonheck/typedrop.git