type Shape = { kind: 'circle'; r: number } | { kind: 'square'; size: number }
function area(shape: Shape): number {
switch (shape.kind) {
case 'circle':
return Math.PI * shape.r ** 2
case 'square':
return shape.size ** 2
default: {
const unreachable: never = shape
throw new Error(`Unhandled shape: ${JSON.stringify(unreachable)}`)
}
}
}
Add { kind: 'triangle'; ... } to the union and the default branch stops compiling, because shape there is no longer never. Much better than finding out at runtime.