intermediate

Discriminated unions

Represent finite state machines, API variants, exhaustive switches, and impossible states.

A discriminated union gives every variant a shared literal discriminant such as `kind` or `status`. Switching on that field narrows the payload. This models request states, domain events, command results, and workflows where impossible combinations should not compile.

					type State =
  | { status: 'loading' }
  | { status: 'success'; data: string }
  | { status: 'error'; error: Error };
				

Use exhaustive handling with `never` in the default branch. If the discriminant widens to `string`, narrowing loses power.

On interviews: explain why one union beats one object with many optional state fields.

Common pitfalls: mixing similar APIs and forgetting edge cases during live coding.

The trade-off is often clarity versus safety or expressiveness versus maintainability. Checklist:

  • Choose a stable discriminant.
  • Use exhaustive switches.
  • Avoid wide string discriminants.