Skip to main content

Exhaustive Switch

TypeScript
tip

The ts-pattern package feels like a cleaner approach to the problem.

Lets assume we have the following scenario:

type Status = 'pending' | 'in-progress';

function checkStatus(status: Status): void {
switch (status) {
case 'pending':
// do something...
break;
case 'in-progress':
// do something...
break;
}
}

At first this feels like a good thing to do. However, if we extend the Status type to include a completed status we don't get any warning or errors from TypeScript that we need to add another case to our switch.

We could add a default case to the switch to at least get an Error at runtime:

switch (status) {
// ...
default:
throw new Error(`Unknown status: ${status}`);
}

But this will only get recognized at runtime or maybe even when it made its way into production. Ideally we would like a way where we are forced to add another case to check for the newely added status.

To achieve this we can use the fact that TypeScript resolves the type of status to never in the default case when all possibilities have been exhausted:

switch (status) {
// ...
default:
// This causes a type error when not exhausted
const _exhaustive: never = status;
throw new Error();
}