A discriminated union is a union where every member has a shared literal property (the discriminant). TypeScript uses it to narrow types in a switch:
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'rectangle'; width: number; height: number }
function area(shape: Shape): number {
switch (shape.kind) {
case 'circle': return Math.PI * shape.radius ** 2;
// ^ TypeScript: shape is Circle ✅
case 'rectangle': return shape.width * shape.height;
// ^ TypeScript: shape is Rectangle ✅
}
}neverThe never type represents impossible values. If you add a new shape variant and forget to handle it, TypeScript catches it via assertNever:
function assertNever(x: never): never {
throw new Error('Unhandled: ' + JSON.stringify(x));
}
// In the switch default:
default: return assertNever(shape);
// If Triangle is not handled, shape is still Triangle here → TypeScript error:
// Argument of type 'Triangle' is not assignable to parameter of type 'never'area(shape: Shape)| Shape | Formula |
|---|---|
square | side² |
rectangle | width × height |
triangle | (base × height) / 2 |
rhombus | (d1 × d2) / 2 |
Sample tests