Exhaustive pattern matching helps you check all possible cases in your code. It makes sure you don't miss any option, so your program works correctly and safely.
Exhaustive pattern matching in Typescript
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'square'; size: number }
| { kind: 'rectangle'; width: number; height: number };
function area(shape: Shape): number {
switch (shape.kind) {
case 'circle':
return Math.PI * shape.radius ** 2;
case 'square':
return shape.size ** 2;
case 'rectangle':
return shape.width * shape.height;
default:
const _exhaustiveCheck: never = shape;
return _exhaustiveCheck;
}
}The default case with never type ensures all cases are handled.
If a new shape is added, TypeScript will show an error if you forget to handle it.
type Status = 'loading' | 'success' | 'error'; function handleStatus(status: Status) { switch (status) { case 'loading': console.log('Loading...'); break; case 'success': console.log('Success!'); break; case 'error': console.log('Error occurred'); break; default: const _exhaustiveCheck: never = status; return _exhaustiveCheck; } }
type Response =
| { type: 'text'; content: string }
| { type: 'json'; data: object };
function processResponse(response: Response) {
switch (response.type) {
case 'text':
return response.content;
case 'json':
return JSON.stringify(response.data);
default:
const _exhaustiveCheck: never = response;
return _exhaustiveCheck;
}
}This program defines a Shape type with three kinds. The area function uses exhaustive pattern matching to calculate the area. It prints the area for each shape.
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'square'; size: number }
| { kind: 'rectangle'; width: number; height: number };
function area(shape: Shape): number {
switch (shape.kind) {
case 'circle':
return Math.PI * shape.radius ** 2;
case 'square':
return shape.size ** 2;
case 'rectangle':
return shape.width * shape.height;
default:
const _exhaustiveCheck: never = shape;
return _exhaustiveCheck;
}
}
const myCircle: Shape = { kind: 'circle', radius: 3 };
const mySquare: Shape = { kind: 'square', size: 4 };
const myRectangle: Shape = { kind: 'rectangle', width: 5, height: 2 };
console.log('Circle area:', area(myCircle));
console.log('Square area:', area(mySquare));
console.log('Rectangle area:', area(myRectangle));Exhaustive pattern matching helps catch missing cases at compile time, reducing bugs.
Time complexity depends on the number of cases, usually O(1) for switch statements.
Common mistake: forgetting the default case with never type, which disables exhaustiveness checking.
Use exhaustive matching when you want safety and clarity over your union types.
Exhaustive pattern matching checks all possible cases in a union type.
It uses a switch statement with a default case that assigns to never to ensure completeness.
This technique helps prevent bugs by making sure you handle every case explicitly.