简体   繁体   中英

Why is this TypeScript exhaustive switch check not working?

Why does the following switch default case not lead to an exhaustive check where item is correctly identified as never?

enum Type {
    First,
    Second
}

interface ObjectWithType {
    type: Type;
}

const array: ObjectWithType[] = [];

for (const item of array) {
    switch (item.type) {
        case Type.First:
            break;
        case Type.Second:
            break;
        default: {
            const unhandledItem: never = item;
            throw new Error(`Unhandled type for item: ${unhandledItem}`);
        }
    }
}

Typescript playground link

It's not working because it's not the item that has never type, it's the item.type .

If you modify your code like so, it will work:

const unhandledItem: never = item.type;
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^

As @thedude said, the problem is that you're using item instead of item.type .

You can correct the problem and make the code simpler by grabbing type from item early and then using that; in the default , the type of type will automatically be narrowed to never :

for (const item of array) {
    const {type} = item;
    switch (type) {
        case Type.First:
            break;
        case Type.Second:
            break;
        default: {
            throw new Error(`Unhandled type for item: ${type}`);
            // The type here is automatically narrowed  ^^^^  to `never`
        }
    }
}

Playground link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM