The `never` type represents a value with no possible type left. It is useful as a compiler check: if a type guard has handled every member of a union, the remaining value can be assigned to `never`. If an unhandled type remains, that assignment fails. section 7.5.1
Check an exhaustive switch
In `src/index.ts`, a tax calculation returns `string | number`. A `switch (typeof taxValue)` handles `"number"` and `"string"`; its `default` clause contains `let value: never = taxValue`. The assignment checks that no declared type remains unhandled. section 7.5.1
Listing 7.28 Using the never type in the index.ts file in the src folder
function calculateTax(amount: number, format: boolean): string | number {
const calcAmount = amount * 1.2;
return format ? `$${calcAmount.toFixed(2)}` : calcAmount;
}
let taxValue = calculateTax(100, false);
switch (typeof taxValue) {
case "number":
console.log(`Number Value: ${taxValue.toFixed(2)}`);
break;
case "string":
console.log(`String Value: ${taxValue.charAt(0)}`);
break;
default:
let value: never = taxValue;
console.log(`Unexpected type for value: ${value}`);
}
The complete listing shows the union-producing function and the `never` assignment in the switch’s default clause. section 7.5.1
`never` can also reveal an unusable inferred type. With the illustrated `strictNullChecks` configuration, an empty array is inferred as `never[]`, so pushing a `string | number` value produces an error. Give the array an asserted type or initialize it with values from which the compiler can infer a useful type. section 9.2.3
Find an impossible intersection
If two intersected object types require the same `contact` property to be `number` and `string`, its merged type is `never`. Neither a number nor a string satisfies it. Changing the properties to compatible object shapes allows their fields to merge instead. section 10.3.2
