Есть фигуры разных видов. Написать функцию area(shape), которая считает площадь. Типизировать так, чтобы при добавлении новой фигуры компилятор заставил обработать её.
// Дискриминированное объединение: общее литеральное поле kindtype Circle = { kind: 'circle'; radius: number };type Square = { kind: 'square'; side: number };type Rectangle = { kind: 'rectangle'; width: number; height: number };type Shape = Circle | Square | Rectangle;function area(shape: Shape): number { switch (shape.kind) { case 'circle': return Math.PI * shape.radius ** 2; // тут shape сужен до Circle case 'square': return shape.side ** 2; case 'rectangle': return shape.width * shape.height; default: // exhaustiveness check: если добавят новый kind и забудут case, // сюда попадёт непустой тип → ошибка компиляции const _exhaustive: never = shape; return _exhaustive; }}
Как работает проверка полноты
В default все известные варианты уже отсечены сужением, поэтому shape имеет тип never. Присваивание never-переменной проходит. Но если добавить type Triangle = ... в union и не написать case 'triangle', то shape в default станет Triangle, и const _exhaustive: never = shape не скомпилируется — компилятор укажет на пропущенную ветку.