TypeDrop
2026-04-29 Challenge
2026-04-29
Easy
Typed Shopping Cart Aggregator
You're building the order summary engine for an e-commerce storefront. Raw cart payloads arrive as `unknown` from a client-side checkout form; your engine must validate them, compute per-line totals with applied discounts, and return a strongly-typed order summary — with zero `any`.
Goals
- Define `Discount`, `CartItem`, `LineTotal`, `OrderSummary`, `CartValidationError`, and `CartResult` types as specified in the requirements.
- Implement `applyDiscount` using exhaustive discriminated-union narrowing on `Discount`, clamping the result to a minimum of 0.
- Implement `parseCartItem` to validate an `unknown` value into a `CartItem`, throwing a typed `CartValidationError` on any invalid field.
- Implement `processCart` to parse an `unknown` array, aggregate line totals into an `OrderSummary`, and return a `CartResult` discriminated union.
challenge.ts
// Core types and main function signature
type Discount =
| { kind: "percentage"; rate: number } // e.g. 0.1 = 10%
| { kind: "fixed"; amount: number }; // absolute deduction per item
type CartItem = {
id: string;
name: string;
quantity: number; // positive integer
unitPrice: number; // >= 0
discount?: Discount;
};
type CartResult =
| { kind: "success"; summary: OrderSummary }
| { kind: "error"; error: CartValidationError };
// Validate an unknown payload and produce a typed order summary
function processCart(raw: unknown): CartResult { /* TODO */ }
Hints (click to reveal)
Hints
- Use a `switch` on `discount.kind` (or `if`/`else` with narrowing) inside `applyDiscount` — TypeScript will enforce exhaustiveness if you add a `never` check in the default branch.
- In `parseCartItem`, narrow `raw` step-by-step: first check `typeof raw === 'object' && raw !== null`, then use `'id' in raw` guards before accessing properties — no `as` needed.
- The `CartValidationError` you throw inside `parseCartItem` is a plain object, not an `Error` instance — catch it in `processCart` and check its `kind` to wrap it in a `CartResult`.
Useful resources
Or clone locally
git clone -b challenge/2026-04-29 https://github.com/niltonheck/typedrop.git