打字稿:联合类型中的接口导致实例错误

时间:2015-04-16 18:54:59

标签: typescript typescript1.4

我用谷歌搜索了最后一小时,我没有找到一个很好的答案或解释我的问题。

我有一个成员变量被定义为一个联合类型,一个原语(数字)或一个接口(KnockoutObservable),我不能使用instanceof或typeof typeguards而不会产生错误。我正在使用带有Typescript 1.4的VS2013更新4。我已经设置了几个例子来证明这个问题:

class foo {
    foo() {}
}

class bar {
    bar() {}
}

interface baz {
    baz();
}

// This case breaks
    var var1: number|foo;

    if (typeof var1 === "number") {
        var1 = 5;
    }
    // Generates error "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter."
    else if (var1 instanceof foo) {
        var1.foo();
    }

    // This also breaks, same error as above
    if (var1 instanceof number) {
        var1 = 5;
    }
    else if (var1 instanceof foo) {
        var1.foo();
    }

    // This case works
    var var2: foo|bar;

    if (var2 instanceof foo) {
        var2.foo();
    }
    else if (var2 instanceof bar) {
        var2.bar();
    }

    // This case breaks as well
    var var3: foo|baz;

    if (var3 instanceof foo) {
        var3.foo();
    }
    // Generates error: "Cannot find name 'baz'."
    else if (var3 instanceof baz) {
        var3.baz();
    }

我的问题是为什么案例1和3会破裂?我们正在创建KnockoutJS组件,其中参数可以是可观察的或原始的。由于KnockoutObservable是一个接口,因此在我们的模式中几乎可以关闭能够使用union类型;如果我们希望参数是我们必须恢复使用'any'。

我发现的一些事情(例如here)似乎意味着这在1.5中得到修复。有人可以给我这个吗?

1 个答案:

答案 0 :(得分:2)

请注意,在函数体中的任何位置分配变量会“关闭”该变量上的类型保护,因此我从此示例中删除了分配。

基本上,情况是按预期工作,应该工作但不工作的情况,以及由于接口没有运行时类型信息而无法工作的情况。 instanceof是一个JavaScript运算符,用于检查对象的原型链,而不是用于执行类型操作的TypeScript构造。

    var var1: number|foo;
    // OK
    if (typeof var1 === "number") { }

    // Bug #2775
    // https://github.com/Microsoft/TypeScript/issues/2775
    if (var1 instanceof foo) { }
    if (var1 instanceof number) { }

    // OK
    var var2: foo|bar;
    if (var2 instanceof foo) { }
    if (var2 instanceof bar) { }

    // TypeScript does not have reflection; there is no
    // value 'baz' to 'instanceof' at runtime.
    if (var3 instanceof baz) {
        var3.baz();
    }

关于x instanceof number的错误也是故意的;没有运行时值number。你可能想写x instanceof Number;这是一个错误(42 instanceof Numberfalse,而不是true。)