我用谷歌搜索了一个小时,但没有找到适合我的问题的答案或解释。
我有一个成员变量定义为一个联合类型,一个原始(数字)或一个接口(interface)(KnockoutObservable),我不能在不产生错误的情况下使用 instanceof 或 typeof 类型保护。我正在使用带有 Typescript 1.4 的 VS2013 update 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 是一个接口(interface),这几乎无法在我们的模式中使用联合类型;如果我们希望参数为 either,我们必须恢复使用“any”。
我发现的一些关于此的内容(例如 here )似乎暗示这在 1.5 中已修复。谁能告诉我这件事的真相?
最佳答案
请注意,在函数主体中的任何位置为变量赋值会“关闭”该变量的类型保护,因此我已从该示例中删除了赋值。
基本上,有一种情况按预期工作,一种情况应该工作但没有工作,还有一种情况不工作,因为没有接口(interface)的运行时类型信息。 instanceof
是一个 JavaScript 运算符,用于检查对象的原型(prototype)链,而不是用于执行类型操作的 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
)。
关于Typescript:联合类型中的接口(interface)导致 Instanceof 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29683613/