我已经用谷歌搜索了一个小时,但我还没有找到一个好的答案或解释。
我有一个成员变量定义为联合类型,原语(Number)或接口(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是一个接口,所以在我们的模式中几乎不能使用联合类型;如果我们希望参数是其中之一,我们必须恢复到使用'any‘。
我发现的一些关于这个的东西(比如here)似乎暗示着这个问题已经在1.5中得到了解决。有人能告诉我这件事的内幕吗?
发布于 2015-04-17 04:16:59
请注意,为函数体中任何位置的变量赋值都会“关闭”该变量的类型保护,因此我从这个示例中删除了赋值。
基本上,有一种情况可以按预期工作,一种应该可以工作但没有,还有一种情况不能工作,因为没有接口的运行时类型信息。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)。
https://stackoverflow.com/questions/29683613
复制相似问题