Engineering practice · 30 MIN
Model legal state transitions
A reducer makes transition rules reviewable and testable.
Represent a request as idle, loading, success or error. An exhaustive switch forces you to handle new event variants when using the TypeScript checker. Runtime logic must also reject illegal transitions: a success response should not overwrite an idle state. In a real application include a request ID so late responses cannot replace newer work.
Treat the function as a small service: define a contract, maintain an invariant, and test the boundaries.
Read the example
type Status = "idle" | "loading"; const status: Status = "loading"; console.log(status);
Check the expected output
loading
Your challenge
Input is an array containing "start", "success", "fail", "reset". Begin idle. start changes idle/error/success to loading; success/fail only apply while loading; reset always returns idle. Return the final state.
Solution cost: O(n) events. time · O(1) space
Common trap
Compile-time exhaustiveness does not prevent a response from an older request winning a race.
Further reading: TypeScript: discriminated unions
Next lesson: Keep generic grouping type safe →