Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么';instanceof';在TypeScript中,给我一个错误"';Foo';仅引用类型,但在此处用作值;?_Javascript_Typescript_Instanceof - Fatal编程技术网

Javascript 为什么';instanceof';在TypeScript中,给我一个错误"';Foo';仅引用类型,但在此处用作值;?

Javascript 为什么';instanceof';在TypeScript中,给我一个错误"';Foo';仅引用类型,但在此处用作值;?,javascript,typescript,instanceof,Javascript,Typescript,Instanceof,我写了这段代码 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似乎不喜欢这样。i

我写了这段代码

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

instanceof
与类而不是接口一起工作

发生什么事? 问题在于,这是一个来自JavaScript的构造,在JavaScript中,
instanceof
需要右侧操作数的值。 具体来说,在
x实例中,Foo
JavaScript将执行运行时检查,以查看
Foo.prototype
是否存在于
x
的原型链中的任何位置

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

TypeScript试图告诉你这是不可能的
Foo
只是一种类型,它根本不是一个值

“我能做什么来代替的
实例?”
你可以调查一下

“但是如果我只是从
接口
切换到
,会怎么样?” 您可能会尝试从
接口
切换到
,但您应该意识到,在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;

在本例中,您有相同类型的
x
y
,但如果您尝试在其中一个上使用
instanceof
,则在另一个上会得到相反的结果。因此,如果你利用TypeScript中的结构类型,那么,
instanceof
不会真正告诉你很多关于类型的信息。

丹尼尔·罗森瓦瑟可能是对的,但我想对他的答案做一个修改。完全可以检查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

如果要检查的接口具有不同的属性/函数,则在运行时使用正在使用的接口执行类型检查

范例

let pet = getSmallPet();

if ((pet as Fish).swim) {
    (pet as Fish).swim();
} else if ((pet as Bird).fly) {
    (pet as Bird).fly();
}

当检查对象是否符合接口签名时,我认为适当的方法是考虑使用“类型谓词”:

请参见下面@4castle的答案。否则,你是对的,我会把它做成
Foo | string
。可能的重复和可能的重复(我真的不想单枪匹马地敲打它)@Jenny O'Reilly,现在这绝对是可能的重复!我花了好长时间才发现那个!所以基本上,我没有从答案中得到更好的答案。上课?因为你很详细。但在你提到“你可能被诱惑”的同时,我感到困惑。那么,如果我必须比较所有属性,而不是像文档中那样比较类型卫士的swim属性呢?这里的要点是
instanceof
与类而不是接口一起工作。我想这需要强调一下。如果我了解鸭子并将函数swim()添加到我的鸟界面中,会怎么样?难道不是每一只宠物都会被归类为一类守卫中的鱼吗?如果我有三个接口,每个接口有三个函数,两个接口与另一个接口重叠?@Kayz如果没有唯一标识接口的属性/函数,就无法真正区分它们。您的宠物实际上可能是一只
鸭子
,您键入guard,它将变成
,但在调用
swim()
时仍然没有运行时异常。建议您创建1级通用界面(例如,
Swimmable
)并将您的
swim()
函数移动到那里,然后键入guard仍然可以使用
((宠物作为Swimmable).swim
。为了防止类型转换,您可以在pet
条件下使用
'swim'。它会将其缩小到必须定义
swim
的子集(例如:
鱼|哺乳动物