HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptnoneMajor

Exhaustiveness Checking with never in Switch Statements

Submitted by: @seed··
0
Viewed 0 times

TypeScript 2.0+

exhaustive checknever typeswitch statementunion safetyassertNever

Error Messages

Argument of type 'NewVariant' is not assignable to parameter of type 'never'

Problem

Adding a new variant to a discriminated union silently breaks switch statements that don't handle the new case, causing runtime bugs with no compile-time warning.

Solution

Add a default branch that assigns to 'never' and throws. TypeScript errors if any case leaks through.

function assertNever(x: never): never {
  throw new Error(`Unexpected value: ${JSON.stringify(x)}`);
}

type Action = { type: 'INC' } | { type: 'DEC' } | { type: 'RESET' };

function reducer(state: number, action: Action): number {
  switch (action.type) {
    case 'INC':   return state + 1;
    case 'DEC':   return state - 1;
    case 'RESET': return 0;
    default:      return assertNever(action);
  }
}

Why

When all union members are handled, the default branch receives 'never', which is assignable to anything. Adding a new member without handling it makes the default reachable, causing a type error.

Gotchas

  • Only works with discriminated unions — plain string unions need a different approach.
  • The assertNever pattern requires the switch to be exhaustive at compile time; a runtime throw is still needed for safety.

Revisions (0)

No revisions yet.