为什么 TypeScript 中的 'instanceof' 会给我错误“'Foo' 仅指一种类型,但在这里被用作值。”?

新手上路,请多包涵

我写了这段代码

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 许可协议

阅读 1.5k
2 个回答

TL;博士

instanceof 适用于类,而不是接口或类型别名。


TypeScript 想告诉我什么?

问题是 instanceof 是 JavaScript 的构造,而在 JavaScript 中, instanceof 期望右侧操作数的 _值_。具体来说,在 x instanceof Foo JavaScript 将执行运行时检查以查看 Foo.prototype 是否存在于 x 的原型链中的任何位置。

但是,在 TypeScript 中, interface 没有发射。 type 别名也是如此。这意味着 FooFoo.prototype 在运行时都不存在,所以这段代码肯定会失败。

TypeScript 试图告诉你这 永远 行不通。 Foo 只是一个类型,根本不是一个值!

如果你来自另一种语言,你可能打算在这里使用一个类。类 确实会 在运行时创建值,但是您可能希望在下面阅读一些关于这些的注释。

“如果我仍然想要 type 或 --- ,我能做些什么来代替 instanceof interface ?”

您可以查看 类型保护和用户定义的类型保护

“但如果我只是从 interface 切换到 class 怎么办?”

您可能很想从 interface 切换到 class ,但您应该意识到在 TypeScript 的结构类型系统(事物主要 _基于形状_)中,您可以生成任何对象具有与给定类相同的形状:

 class C {
    a: number = 10;
    b: boolean = true;
    c: string = "hello";
}

let x = new C()
let y = {
    a: 10, b: true, c: "hello",
}

// Works!
x = y;
y = x;

在这种情况下,您有 xy 具有相同的类型,但是如果您尝试在其中任何一个上使用 instanceof ,您将得到相反的结果在另一。所以 instanceof 如果你在 TypeScript 中利用结构类型,它并不会 真正 告诉你太多关于类型的信息。

原文由 Daniel Rosenwasser 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以使用 in 运算符缩小 来检查您需要的元素是否在对象中。

使用此方法,您可以验证 x 是字符串还是 Foo

 if ('abcdef' in x) {
    // x is instance of Foo
}

原文由 Giuseppedes 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题