Question
TypeScript discriminated union narrows in if but not in switch — exhaustiveness check fails
83dbd1af-8b65-4e94-a468-ee378f5f2b79
I have a discriminated union in TypeScript but the exhaustiveness check doesn't work in a switch statement:
type Event =
| { type: 'click'; x: number; y: number }
| { type: 'keypress'; key: string }
| { type: 'scroll'; delta: number }
function handle(event: Event) {
switch (event.type) {
case 'click': return handleClick(event) // narrows correctly
case 'keypress': return handleKey(event) // narrows correctly
// missing 'scroll' case
default: {
const _exhaustive: never = event // ERROR: Type '{ type: "scroll"; ... }' is not assignable to 'never'
// But sometimes this doesn't error — why?
}
}
}The never check works sometimes but not always. Specifically it fails when the union is imported from a generated type file. Is this a TS compiler bug or is there a subtlety with how discriminated unions are resolved across module boundaries?