0Pricing
TypeScript Academy · Lesson

Exhaustiveness Checking with never

Use never to ensure all union cases are handled.

Exhaustiveness Checking with never is a free TypeScript Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Welcome

Exhaustiveness checking uses the `never` type to ensure every case of a union is handled. When you add a new union member, TypeScript will tell you exactly where to update your code.

The Exhaustiveness Problem

When you switch on a union type and forget a case, JavaScript silently falls through. TypeScript can detect this with a never check.
type Shape = 'circle' | 'square';
function area(s: Shape): number {
  if (s === 'circle') return 3.14;
  if (s === 'square') return 1;
  // What if we add 'triangle'?
}

The never Exhaustiveness Pattern

Assign the remaining value to `never`. If TypeScript infers a non-never type, it means you have an unhandled case.
function assertNever(x: never): never {
  throw new Error('Unexpected value: ' + x);
}
function area(s: Shape): number {
  switch (s) {
    case 'circle': return 3.14;
    case 'square': return 1;
    default: return assertNever(s);
  }
}

Adding a New Union Member

If you add 'triangle' to the Shape union, TypeScript will error at `assertNever(s)` telling you to handle the new case.
type Shape = 'circle' | 'square' | 'triangle';
// Now TypeScript errors on assertNever(s) because s is 'triangle'
// — it's not never!

Inline never Check

You can do an inline exhaustiveness check without a helper function.
function handle(shape: Shape): string {
  switch (shape.kind) {
    case 'circle': return 'circle';
    case 'square': return 'square';
    default:
      const _: never = shape; // Error if not exhaustive
      throw new Error('Unknown shape');
  }
}

Exhaustiveness Without switch

Use the same technique in if/else chains.
function process(action: Action): void {
  if (action.type === 'A') { /* ... */ }
  else if (action.type === 'B') { /* ... */ }
  else {
    const _: never = action; // exhaustive
  }
}

never in Generic Type Constraints

never is the bottom type and is useful in conditional types to represent impossible branches.
type NonNullable<T> = T extends null | undefined ? never : T;
// Removes null and undefined from T

Using never for Impossible States

Never is useful for modeling states that should be impossible in your type system.
type State<T> =
  | { kind: 'loading' }
  | { kind: 'success'; data: T }
  | { kind: 'error'; msg: string };
// There should never be a state with kind: 'unknown'

never in Conditional Types

never is used in conditional types to filter out unwanted type members.
type NonFunctions<T> = {
  [K in keyof T]: T[K] extends Function ? never : K
}[keyof T];
// Returns keys whose values are not functions

never Propagates Through Unions

never is an identity element for union types — T | never = T.
type T = string | never; // string
type U = never | number | never; // number

The assertNever Helper

A simple assertNever utility is something every TypeScript project should have for exhaustiveness checks.
function assertNever(value: never, message?: string): never {
  throw new Error(message ?? `Unhandled: ${JSON.stringify(value)}`);
}

Quick Check

What happens at the `default: assertNever(s)` line if `s` still has a possible type that is not handled?

Recap

Use assertNever(x: never) in switch default cases to get compile errors when union members are not handled. This ensures your code stays correct as the union grows over time.

Frequently asked questions

Is the “Exhaustiveness Checking with never” lesson free?

Yes — the full text of “Exhaustiveness Checking with never” is free to read here on the web, and the TypeScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.

What will I learn in “Exhaustiveness Checking with never”?

Use never to ensure all union cases are handled. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start TypeScript Academy?

No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Exhaustiveness Checking with never” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this TypeScript Academy lesson?

Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. typeof and Truthiness Narrowing
  2. instanceof and in Narrowing
  3. User-Defined Type Guard Functions
  4. Exhaustiveness Checking with never
← Back to TypeScript Academy