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

问题描述 投票:40回答:2

我写了这段代码

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

javascript typescript instanceof
2个回答
60
投票

What's going on

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

但是,在TypeScript中,interfaces没有发射。这意味着在运行时既不存在Foo也不存在Foo.prototype,因此这段代码肯定会失败。

TypeScript试图告诉你这可能永远不会奏效。 Foo只是一种类型,它根本不是一个价值!

"What can I do instead of instanceof?"

你可以看看type guards and user-defined type guards

"But what if I just switched from an interface to a 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,你将得到相反的结果。因此,如果您正在利用TypeScript中的结构类型,instanceof将不会真正告诉您类型。


1
投票

丹尼尔罗森瓦瑟可能是对的和花花公子,但我觉得他正在修改他的答案。完全有可能检查x的实例,请参阅代码段。

但是分配x = y也同样容易。现在x不是C的实例,因为y只有C的形状。

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

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

console.log('x is C? ' + (x instanceof C)) // return true
console.log('y is C? ' + (y instanceof C)) // return false
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.