| name | typescript-exhaustive-switch |
| description | Require exhaustive switch handling over TypeScript discriminated unions and enums by adding a `never` check in the default case. Apply when writing or reviewing a `switch` over a union or enum, and when adding a new variant to an existing union or enum. |
| paths | ["**/*.ts","**/*.tsx"] |
Exhaustive switch handling
In switch statements over discriminated unions or enums, use a never check in the default case so newly added variants cause compile-time failures until handled.
Pattern
switch (event.kind) {
case "created":
return handleCreated(event);
case "deleted":
return handleDeleted(event);
default: {
const unhandled: never = event;
throw new Error(`Unhandled variant: ${JSON.stringify(unhandled)}`);
}
}
The const unhandled: never assignment is the whole point: once a new variant is added to the union or enum, that assignment stops type-checking and the compiler points at every switch that has not been updated.
Rules
- Every
switch over a discriminated union or enum gets the never default.
- Do not use a permissive default that silently swallows unknown variants — that turns a compile-time error into a runtime surprise.
- The same applies to exhaustive
if/else if chains over a discriminant: end with a never-typed binding rather than a bare else.
When reviewing
If a new variant is added to a union or enum, check that every switch over it was updated. A switch without the never default is the reason such a variant can be missed, so flag it even when the current code happens to be complete.