typescript / intermediate
Snippet
Exhaustive Pattern Matching with Discriminated Unions and Never
Discriminated unions combine a literal tag property ('kind') with TypeScript's type narrowing. By passing the default switch branch to a function accepting only the 'never' type, the compiler guarantees at build time that every union member is handled. Adding a new shape variant without updating the switch statement produces an explicit compile error.
snippet.ts
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
type Circle = { kind: "circle"; radius: number };type Square = { kind: "square"; sideLength: number };type Rectangle = { kind: "rectangle"; width: number; height: number };type Shape = Circle | Square | Rectangle;function assertUnreachable(x: never): never {throw new Error(`Unexpected object: ${JSON.stringify(x)}`);}function calculateArea(shape: Shape): number {switch (shape.kind) {case "circle":return Math.PI * shape.radius ** 2;case "square":return shape.sideLength ** 2;case "rectangle":return shape.width * shape.height;default:return assertUnreachable(shape);}}
Breakdown
1
type Shape = Circle | Square | Rectangle;
Defines a discriminated union type where each member shares a common 'kind' field with unique literal values.
2
function assertUnreachable(x: never): never {
Helper function expecting the 'never' type, representing a state that should be impossible if all union branches are exhaustively checked.
3
return assertUnreachable(shape);
Triggers a type error during compilation if any variant of the Shape union is missing from the switch statement.