Command Palette

Search for a command to run...

Hectal
Phase 17: Interviews and Capstone
TypeScript · Exercise 6 of 6 Previous
Advanced

Capstone: A Typed Store with Branded IDs

Build a small typed state store for a shopping cart. Three pieces: the action type, a reducer, and a generic Store<S, A> class.

CartAction is a union of { type: 'add'; id: ProductId }, { type: 'remove'; id: ProductId } and { type: 'checkout' }. reducer(state, action) returns the new CartState and ends its switch with assertNever(action): add increases the quantity of an existing item or adds one with quantity 1, remove deletes the item, checkout sets the status to 'checkedOut'.

Store<S, A> takes a reducer (state: S, action: A) => S and a starting state. It has getState(), dispatch(action) (run the reducer, then tell every listener) and subscribe(listener), which returns a function that removes the listener. The driver code at the bottom must print items: 1, open, items: 1, open, items: 2, open, items: 1, open, then checkedOut.

Keep the helpers and the driver code. A raw string like "p1" must not be accepted as a ProductId.

What Check tests

  1. Your code has no type errors
  2. The driver prints the expected five lines
  3. A raw string is not a ProductId
  4. An unknown action is rejected
  5. The reducer ends in assertNever
  6. A listener must take the state type

Stuck? One hint at a time

The solution unlocks after your first Check. Try first: that is where the learning happens.

Runs in your browser. Your code is saved here.

Console

Nothing printed yet.