我用谷歌搜索了最后一小时,我没有找到一个很好的答案或解释我的问题。
我有一个成员变量被定义为一个联合类型,一个原语(数字)或一个接口(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中得到修复。有人可以给我这个吗?
答案 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 Number
是false
,而不是true
。)