liveBook · Manning

Never type

As explained in Essential TypeScript 5, Third Edition

The never type is a TypeScript type representing values that can never occur, such as the result of a function that cannot complete normally.

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

How Essential TypeScript 5, Third Edition covers it

How deep it goes
Works through a switch assignment, an empty-array compiler error, and an impossible property intersection; does not develop function return types.
Examples
Shows a tax-value switch, a failed push into an empty array, and conflicting `contact` property types.
What it assumes
Builds on JavaScript’s `typeof` and TypeScript union types while introducing the `never` assignment as an exhaustive check.
What you can do after
Diagnose/debug with it by checking unhandled union members and identifying arrays or intersections whose inferred types accept no values.
How it connects
Connects `never` to union types, type guards, `strictNullChecks`, empty-array inference, and intersection types.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Essential TypeScript 5, Third Edition. The section links point to the parts of the book it draws on.