Discriminated union
A discriminated union is a union type whose variants share a literal-typed property (the discriminant) that uniquely identifies each variant — typically named 'type', 'kind', or 'tag'. The discriminant lets TypeScript narrow the union via a switch or if-check, with exhaustive case handling enforced by the type system.
Discriminated unions are TypeScript's idiomatic way to model alternatives: a Result that's either Ok or Err, a Shape that's a Circle or Square or Triangle, a NetworkState that's Idle or Loading or Loaded or Error. The pattern produces exhaustiveness checking: forget a case in a switch, and either the return type widens or the never-check fires. The discipline is to use the same discriminant name across the codebase (Stride convention: 'kind'). The pattern is the antidote to the 'object with optional fields where exactly one is set' anti-pattern that produces undefined-checks throughout the consuming code.
Related terms
- Type narrowing
Type narrowing is TypeScript's ability to refine a value's type within a conditional branch based on runtime checks — typeof, instanceof, in operator, equality checks, custom type predicates.
- TypeScript strict mode
TypeScript's strict mode enables a bundle of compiler flags that produce stricter type checking — noImplicitAny, strictNullChecks, strictFunctionTypes, strictBindCallApply, alwaysStrict, strictPropertyInitialization, noImplicitThis.
- Branded type
A branded type is a TypeScript pattern that distinguishes structurally-identical types by adding a phantom 'brand' property — UserId and ProductId can both be string at runtime but cannot be assigned to each other at compile time.