我写了这段代码
interface Foo {
abcdef: number;
}
let x: Foo | string;
if (x instanceof Foo) {
// ...
}
但是 TypeScript 给了我这个错误:
'Foo' only refers to a type, but is being used as a value here.
为什么会这样?我以为 instanceof
可以检查我的值是否具有给定的类型,但 TypeScript 似乎不喜欢这样。
原文由 Daniel Rosenwasser 发布,翻译遵循 CC BY-SA 4.0 许可协议
TL;博士
instanceof
适用于类,而不是接口或类型别名。TypeScript 想告诉我什么?
问题是
instanceof
是 JavaScript 的构造,而在 JavaScript 中,instanceof
期望右侧操作数的 _值_。具体来说,在x instanceof Foo
JavaScript 将执行运行时检查以查看Foo.prototype
是否存在于x
的原型链中的任何位置。但是,在 TypeScript 中,
interface
没有发射。type
别名也是如此。这意味着Foo
和Foo.prototype
在运行时都不存在,所以这段代码肯定会失败。TypeScript 试图告诉你这 永远 行不通。
Foo
只是一个类型,根本不是一个值!如果你来自另一种语言,你可能打算在这里使用一个类。类 确实会 在运行时创建值,但是您可能希望在下面阅读一些关于这些的注释。
“如果我仍然想要
type
或 --- ,我能做些什么来代替instanceof
interface
?”您可以查看 类型保护和用户定义的类型保护。
“但如果我只是从
interface
切换到class
怎么办?”您可能很想从
interface
切换到class
,但您应该意识到在 TypeScript 的结构类型系统(事物主要 _基于形状_)中,您可以生成任何对象具有与给定类相同的形状:在这种情况下,您有
x
和y
具有相同的类型,但是如果您尝试在其中任何一个上使用instanceof
,您将得到相反的结果在另一。所以instanceof
如果你在 TypeScript 中利用结构类型,它并不会 真正 告诉你太多关于类型的信息。