DEV Community

Cover image for The never type in typescript
Ambuj sahu
Ambuj sahu

Posted on

The never type in typescript

The never type

The never type is used when you are sure that something is never going to happen. It simply represents a state which shouldn’t exist.

It might be return type of function that never returns.


function throwError(errorMsg: string): never { 
    throw new Error(errorMsg); 
}

function loop(): never {
    while(true) {}
}
Enter fullscreen mode Exit fullscreen mode

Here, both reportError and loop type function either throw errors or return infinite loop that will be analyzed by TypeScript control flow as functions with unreachable endpoints, thus specifying their return type as never.

Note When a function is throw-only, it gets the type never if it's an expression, and void if it's a declaration.

function foo() { 
    throw new Error("Should never get here");
}
Enter fullscreen mode Exit fullscreen mode

here foo is () => void. Read more about it in StackOverFlow answer

Exhaustiveness checking

you can use never type for narrowing and turning up to do exhaustive checking in a switch statement.

type Shape = Circle | Square;

function getArea(shape: Shape) {
  switch (shape.kind) {
    case "circle":
      return Math.PI * shape.radius ** 2;
    case "square":
      return shape.sideLength ** 2;
    default:
      const _exhaustiveCheck: never = shape;
      return _exhaustiveCheck;
  }
}
Enter fullscreen mode Exit fullscreen mode

Here getArea function which tries to assign the shape to never will raise the issue that every possible case has not been handled.

Assignability in TypeScript

The never type is assignable to every type; however, no type is assignable to never (except never itself).It can be understood as "the smallest type".

 // ✨ `never` is assignable to all types.
  // It is a subtype of all types.
  let neverValue: never = getNever();


  let numberValue: number = neverValue;  // ✅
  let stringValue: string = neverValue;  // ✅
  let objectValue: object = neverValue;  // ✅
  let unknownValue: unknown = neverValue;  // ✅
  let anyValue: any = neverValue;  // ✅
  let neverValue1: never = neverValue;  // ✅


  neverValue = 1; // ❌
  neverValue = '1'; // ❌
  neverValue = {}; // ❌
  neverValue = anyValue; // ❌
Enter fullscreen mode Exit fullscreen mode

Void Vs Never

The never type looks very similar to void. But the void type can have undefined or null as a value where as never cannot have any value.

let something: void = null;
let nothing: never = null; // Error: Type 'null' is not assignable to type 'never'
Enter fullscreen mode Exit fullscreen mode

Intersection and Union with never type

In intersection types, it absorbs all types, and in union types all types absorb it. This is because never is a subtype of all types.

 type anyTypeUnion = never | any; // any
 type anyTypeIntersection = never & any; // never
Enter fullscreen mode Exit fullscreen mode

References

  1. - Everyday Types
  2. - Stackoverflow
  3. - TypeScript Release notes

Top comments (0)