Exhaustive Typechecking in Typescript

Written 1 week ago

Consider an enum:

enum Color {
  Red,
  Blue,
  Green,
}

that has a switch case:

function whichColor(c: Color): string {
  switch (c) {
    case Color.Red:
      return "Red"
    case Color.Blue:
      return "Blue"
    default:
      return "Unknown color"
  }
}

where we missed Color.Green, and yet no errors!

A simple solution (Typescript 4.9+):

function whichColor(c: Color): string {
  switch (c) {
    case Color.Red:
      return "Red"
    case Color.Blue:
      return "Blue"
    default:
      c satisfies never // <-- Magic
      return "Unknown color"
  }
}

Which leads to:

Error: Type 'Color.Green' does not satisfy the expected type 'never'.

Easy peasy!

…Okay, but how does it work exactly?

“When narrowing, you can reduce the options of a union to a point where you have removed all possibilities and have nothing left. In those cases, TypeScript will use a never type to represent a state which shouldn’t exist.”

See the typescript handbook - never type for authoritative info and more use cases for never.

Satisfies is like as const without readonly and : Type without type widening.

See learningtypescript - the satisfies operator for what the satisfies operator does.

More resources


< sleep-sort