0Pricing
TypeScript Academy · Lesson

The never Type and Impossible States

Model unreachable code and impossible values with never.

The never Type and Impossible States is a free TypeScript Academy lesson on CoddyKit — lesson 2 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.

The never Type

never is the empty type — it represents values that can never occur. No value is assignable to never (except never itself). It marks situations that should be impossible.

// You cannot create a value of type never
function crash(): never {
  throw new Error('boom');
}
try { crash(); } catch (e) { console.log('caught'); }

Functions That Never Return

A function that always throws never returns normally, so its return type is never. This tells callers (and the compiler) that execution stops here.

function fail(message: string): never {
  throw new Error(message);
}
try { fail('invalid'); } catch (e) { console.log('handled'); }

Infinite Loops Return never

A function with an infinite loop also never returns, so it too is typed never. The compiler recognizes that control flow can't continue past it.

function listen(): never {
  while (true) {
    // forever
    break; // (break added so the demo terminates)
  }
  throw new Error('stopped');
}
console.log('listen has return type never');

never vs void

Don't confuse never with void. A void function returns (it just yields no useful value). A never function does not return at all — it throws or loops forever.

function logIt(): void {
  console.log('done'); // returns normally
}
function abort(): never {
  throw new Error('stop'); // never returns
}
logIt();
try { abort(); } catch (e) { console.log('ok'); }

never in Exhaustiveness Checks

The most practical use of never is exhaustiveness checking. In a switch default, assign the variable to a never. If all cases are handled, the variable is already never and it compiles.

type Shape = 'circle' | 'square';

function area(s: Shape): string {
  switch (s) {
    case 'circle': return 'pi r^2';
    case 'square': return 'a^2';
    default:
      const _check: never = s; // ok: all handled
      return _check;
  }
}
console.log(area('square'));

Catching Missing Cases

If someone adds a new union member but forgets a case, the leftover value is no longer never, so the assignment fails to compile. The never check turns a silent gap into a loud error.

type Shape = 'circle' | 'square' | 'triangle';
// If 'triangle' case is missing, assigning s to never
// would error: 'triangle' is not assignable to never.
console.log('Add a case for every member');

never in Impossible Union Branches

When narrowing removes every possibility, the remaining type is never. The compiler knows that branch is unreachable, which can reveal logic mistakes.

function check(x: string | number): void {
  if (typeof x === 'string') {
    console.log('string');
  } else if (typeof x === 'number') {
    console.log('number');
  } else {
    // x is never here
    console.log('unreachable');
  }
}
check('hi');

never as the Bottom Type

never is the bottom type: it is assignable to every other type, because a value that can't exist is vacuously compatible with anything. This is why a throw can appear in any expression position.

function getOrThrow(v: string | null): string {
  return v ?? fail();
}
function fail(): never {
  throw new Error('missing');
}
console.log(getOrThrow('value'));

Filtering Unions to never

In conditional and mapped types, never acts as 'remove this'. Unioning with never changes nothing: T | never is just T. This makes it the natural choice for filtering.

type Keep<T> = T extends string ? T : never;
type R = Keep<'a' | 1 | 'b'>; // 'a' | 'b'
const x: R = 'a';
console.log(x);

Modeling Impossible States

Use never in object shapes to make illegal combinations unrepresentable. Here a 'loading' state cannot also carry data, because the type forbids it.

type State =
  | { status: 'loading'; data?: never }
  | { status: 'ready'; data: number };

const s: State = { status: 'ready', data: 7 };
console.log(s);

never Improves Refactoring Safety

Because never exhaustiveness checks fail when a case is missing, they make refactoring safer: extend a union and the compiler points you to every place that needs updating.

type Cmd = 'start' | 'stop';
function run(c: Cmd): string {
  if (c === 'start') return 'starting';
  if (c === 'stop') return 'stopping';
  const _x: never = c;
  return _x;
}
console.log(run('start'));

Quick Check

Test your understanding of the never type.

Recap: never

You learned that never:

  • Is the empty type — no value can be of type never.
  • Is the return type of functions that throw or loop forever.
  • Powers exhaustiveness checks in switch defaults.
  • Appears in impossible narrowing branches and filters unions in type logic.

Next, we look at void and how it differs.

function assertNever(x: never): never {
  throw new Error('Unexpected: ' + String(x));
}
console.log('assertNever guards exhaustiveness');

Frequently asked questions

Is the “The never Type and Impossible States” lesson free?

Yes — the full text of “The never Type and Impossible States” 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 “The never Type and Impossible States”?

Model unreachable code and impossible values with never. 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 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “The never Type and Impossible States” 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. Understanding unknown vs any
  2. The never Type and Impossible States
  3. The void Type in Functions
  4. Type-Safe Handling of unknown
← Back to TypeScript Academy