小编典典

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

all

我写了这段代码

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 似乎不喜欢这样。


阅读 89

收藏
2022-09-02

共1个答案

小编典典

TL;博士

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


TypeScript 想告诉我什么?

问题是这instanceof是一个来自 JavaScript 的构造,并且在
JavaScript 中,instanceof需要一个右侧操作数的 值。 具体来说,在x instanceof FooJavaScript
中会执行一次运行时检查,看是否Foo.prototype存在于x.

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

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

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

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

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

“但如果我只是从一个切换interface 到一个class呢?”

您可能很想从 a 切换interface到 a 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;

在这种情况下,你有xythat 有相同的类型,但如果你尝试instanceof在其中一个上使用,你会在另一个上得到相反的结果。因此,如果您利用
TypeScript 中的结构类型,instanceof则不会 真正告诉您有关类型的太多信息。

2022-09-02