首页 > 解决方案 > 运行时检查开关是否详尽(当编译时详尽时)

问题描述

我有一个switch涵盖所有编译时间可能性的语句,但是由于该值可以由用户提供,我想在运行时处理意外值。

这似乎是打字稿的类型推断太好的地方它分配类型never(因为从编译器的角度来看,这永远不会发生)并且不会让我访问它的任何字段。

简化示例

type Circle = { shape: "circle", radius: number };
type Rectangle = { shape: "rectangle", length: number, width: number };

function area(shape: Circle | Rectangle): number {
    switch (shape.shape) {
        case "circle": return Math.PI * shape.radius * shape.radius;
        case "rectangle": return shape.length * shape.width;
    }
    throw new Error(`Unexpected shape '${shape.shape}'`); // Error: Property 'shape' does not exist on type 'never'.
}

有没有一种优雅的方法来修复最后一行?(比转换为any或使用下标运算符更优雅)。

标签: typescriptswitch-statement

解决方案


此页面提供了一个解决方案: https ://www.typescriptlang.org/docs/handbook/advanced-types.html

适合您的示例:


    type Circle = { shape: "circle", radius: number };
    type Rectangle =  { shape: "rectangle", length: number, width: number };

    function throwOnNever(x: {shape: string}): never {
        throw new Error(`Unexpected shape: ${x.shape}`);
    }

    function area(shape: Circle | Rectangle): number {    
        switch (shape.shape) {
            case "circle": return Math.PI * shape.radius * shape.radius;
            case "rectangle": return shape.length * shape.width;
            default: return throwOnNever(shape);
        }
    }


推荐阅读