Never

A video lesson on the never type

Programming language design does have a concept of bottom type that is a natural outcome as soon as you do code flow analysis. TypeScript does code flow analysis (?) and so it needs to reliably represent stuff that might never happen.

The never type is used in TypeScript to denote this bottom type. Cases when it occurs naturally:

  • A function never returns (e.g. if the function body has while(true){})
  • A function always throws (e.g. in function foo(){throw new Error('Not Implemented')} the return type of foo is never)

Of course you can use this annotation your self as well

  1. let foo: never; // Okay

However never can only ever be assigned to another never. e.g.

  1. let foo: never = 123; // Error: Type number is not assignable to never
  2. // Okay as the function's return type is `never`
  3. let bar: never = (() => { throw new Error('Throw my hands in the air like I just dont care') })();

Great. Now let’s just jump into its key use case :)

Use case: Exhaustive Checks

You can call never functions in a never context.

  1. function foo(x: string | number): boolean {
  2. if (typeof x === "string") {
  3. return true;
  4. } else if (typeof x === "number") {
  5. return false;
  6. }
  7. // Without a never type we would error :
  8. // - Not all code paths return a value (strict null checks)
  9. // - Or Unreachable code detected
  10. // But because typescript understands that `fail` function returns `never`
  11. // It can allow you to call it as you might be using it for runtime safety / exhaustive checks.
  12. return fail("Unexhaustive!");
  13. }
  14. function fail(message: string): never { throw new Error(message); }

And because never is only assignable to another never you can use it for compile time exhaustive checks as well. This is covered in the discriminated union section.

Confusion with void

As soon as someone tells you that never is returned when a function never exits gracefully you intutively want to think of it as the same as void However void is a Unit. never is a falsum.

A function that returns nothing returns a Unit void. However a function that never returns (or always throws) returns never. void is something that can be assigned (without strictNullChecking) but never can never be assigned to anything other than never.