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) {}
}
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");
}
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;
}
}
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; // ❌
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'
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
Top comments (0)