Advanced TypeScript
Discriminated Unions
A discriminated union models alternatives using a shared literal field such as
kind, type, or status. It makes invalid combinations unrepresentable and gives TypeScript reliable narrowing.- One field identifies the variant
- Model states as alternatives, not flags
- Payload belongs only where valid
- Exhaustiveness protects future changes
- Discriminants work beautifully with reducers and events
type LoadState<T> =
| { kind: "idle" }
| { kind: "loading" }
| { kind: "success"; data: T }
| { kind: "error"; error: Error }
function message(state: LoadState<User>) {
switch (state.kind) {
case "idle": return "Not loaded"
case "loading": return "Loading..."
case "success": return state.data.name
case "error": return state.error.message
}
}| Approach | Problem/Benefit |
|---|---|
| Boolean flags | Can represent impossible states |
| Optional fields | Caller must guess which fields exist |
| Discriminated union | Only valid states are representable |
| assertNever | Future variants force handling |