【问题标题】:Type guard error after updating typescript from 2.0.3 to 2.1.4将打字稿从 2.0.3 更新到 2.1.4 后出现类型保护错误
【发布时间】:2017-04-27 03:05:46
【问题描述】:
class A {
   type: string
}

interface AClass<T extends A> {
    prototype: T
}

function isType<T extends A>(a: A, aClass: AClass<T>): a is T {
    return a.type === aClass.prototype.type
}

class B extends A {
    foo: string
}

class C extends A {}

function check(a: A) {
    if (isType(a, B)) {
        return
    }
    a.type // ok

    if (isType(a, C)) {
        return
    }
    a.type // Property 'type' does not exist on type 'never'.
}

当派生类没有任何独特的属性时会出现错误。这发生在我将 TS 更新到 2.1.4 之后。我的问题是:

  • 为什么会出现错误?我的猜测是 TS 绕过了自定义类型检查并将 AC 视为具有相同类型,因此将无法到达下一条语句,a 将具有类型 never

  • 有没有比在派生类中添加虚拟属性更好的解决方案?

【问题讨论】:

    标签: typescript typescript2.0 typescript2.1


    【解决方案1】:

    你是对的,因为 AC 被编译器认为是相同的类型,因为它们具有相同的确切结构 (Type Compatibility)。

    您不应该添加虚拟属性,如果C 没有其他成员/方法,那么无论如何它都没有意义,您只需使用AB


    编辑

    你可以这样做:

    class A {
        type: "B" | "C";
    }
    
    class B extends A {
        type: "B";
        foo: string
    }
    
    class C extends A {
        type: "C";
    }
    

    编译器现在不会抱怨了,但是你可以得到完全相同的东西:

    class A {
        type: string;
    
        constructor(type: string = "A") {
            this.type = type;
        }
    }
    
    class B extends A {
        foo: string;
    
        constructor(foo: string) {
            super("B");
            this.foo = foo;
        }
    }
    
    let a = new A();
    let b = new B("foo");
    let c = new A("C");
    

    ac 之间的 type 属性不同,即使它们是同一类的实例。

    【讨论】:

    • 一个用例是在 redux 中声明一些动作创建者,其中每种类型的动作由 type 属性的值来区分。这就是为什么我有函数isType
    • 检查我修改后的答案
    • 随着派生类的数量越来越大,它会变得丑陋。就我而言,大约有一百个动作。
    • 如果你使用TS 2.0编译,没有问题。我不知道我是否错过了它,但我没有看到与该问题相关的任何重大更改或更改日志。代码对我来说看起来不错。在运行时,实际上可以到达最后一行,但控制流分析另有说明(a 的类型为never)。这可能是一个错误或什么的。
    • 我编辑中的第二个选项不会随着动作数量的增加而变得难看,也不会导致编译错误。您收到的错误编译不是错误。
    猜你喜欢
    • 2020-06-02
    • 2021-03-25
    • 1970-01-01
    • 2017-05-18
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多