Want a faster signal before interviews? Take the Interview Ready Check →

DAY 18 OF 30

never and exhaustiveness checking

Yesterday, in one sentence

What is the difference between any and unknown?

Interview question

You are handling a response from an API. Would you type it as any or unknown, and why?

never is the type for a value that can never exist. It represents an impossibility.

type Impossible = string & number;
// never, because no value can be both a string and a number

You also get never from narrowingNarrowing. Once type guardsType Guard have ruled out every type in a union typeUnion Type, there is nothing left and the type becomes never.

function describe(id: string | number) {
  if (typeof id === "string") return id;
  if (typeof id === "number") return id;

  return id; // id has type never, all other types have been ruled out
}

An exhaustiveness check uses this to make TypeScript error when a discriminated unionDiscriminated Union gains a member you have not handled. It works because you can only assign a value to a never once narrowing has ruled everything else out.

type Character = { kind: "hero" } | { kind: "villain" };

function describe(character: Character) {
  if (character.kind === "hero") return "saves people";
  if (character.kind === "villain") return "causes trouble";

  const unhandled: never = character; // ok, character is never here
  return unhandled;
}

Add a third member and the assignment stops compiling.

type Character = { kind: "hero" } | { kind: "villain" } | { kind: "antihero" };

function describe(character: Character) {
  if (character.kind === "hero") return "saves people";
  if (character.kind === "villain") return "causes trouble";

  const unhandled: never = character;
  // ❌ character is not never here, "antihero" has not been handled
  return unhandled;
}

That error is the point. Without it, an antihero would fall past both checks and nothing would tell you.

Check yourself

What is the type of rank on the marked line?
type Rank = "alpha" | "beta" | "omega"

function classify(rank: Rank) {
  if (rank === "alpha") return
  if (rank === "beta") return
  if (rank === "omega") return

  rank   // ← here
}
What is the never type in TypeScript?