Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.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 Typescript类变量和错误:";引用一个值,但在此处用作类型。你是说';的类型吗&引用;。到底为什么?_Javascript_Typescript - Fatal编程技术网

Javascript Typescript类变量和错误:";引用一个值,但在此处用作类型。你是说';的类型吗&引用;。到底为什么?

Javascript Typescript类变量和错误:";引用一个值,但在此处用作类型。你是说';的类型吗&引用;。到底为什么?,javascript,typescript,Javascript,Typescript,这适用于Javascript和Typescript: A类{/*…*/} 常量B=类扩展了{/*…*/} var x=新的B(); console.log(x instanceof B,x.constructor.name);//真B 但是如果我试图将x的类型声明为B: var x:B=new B(); 我收到Typescript错误: “B”指的是一个值,但在这里用作类型。你是说“B型”吗 (注意,如果我用简单的const B=A替换const B=class extensed A{/*…

这适用于Javascript和Typescript:

A类{/*…*/}
常量B=类扩展了{/*…*/}
var x=新的B();
console.log(x instanceof B,x.constructor.name);//真B
但是如果我试图将
x
的类型声明为
B

var x:B=new B();
我收到Typescript错误:

“B”指的是一个值,但在这里用作类型。你是说“B型”吗

(注意,如果我用简单的
const B=A
替换
const B=class extensed A{/*…*/}
,我也会得到同样的错误,这是我最初使事情尽可能简单的方法,但在回顾时更新了)

我真的不明白为什么会这样。根据运行时,Javascript
x
是a
B
(如上面的console.log所示)。所有的类都是隐藏在幕后的对象(“值”)(Typescript文档本身就等同于类)。我猜这只是Typescript静态分析的一个局限性——它不能像“a”一样找出“B”是构造函数对象,并跟踪其类型

而且,我也不这么认为,但我想知道,有没有一种方法可以在Typescript中完成这项工作-知道B是像a一样的构造函数对象,并且允许使用B作为类型



另外,我意识到关于“Blah指的是一个值,但在这里被用作一种类型。你的意思是‘typeof Blah’?”有很多问题,但我找不到像上面那样直接的Q&a。如果我错过了,我深表歉意。

当您编写
class
声明时,如

class A { a = 1 }
const B = class extends A { b = 2 };
在TypeScript中,您将两个不同的东西纳入范围,它们都被命名为
A
。一个是名为
A
的值,它是运行时存在的类构造函数。另一个是名为
A
的类型,一个与类实例相对应的TypeScript接口;这样的类型在运行时不存在

还要注意,值有一个类型,但它本身不是一个类型。并且
A
值的类型不是
A
,因为类构造函数本身不是类的实例)。相反,它的类型是A的类型(使用表示),这与类型
new()=>A
(使用表示)类似

值和类型都被命名为
A
,这一事实很方便,但容易混淆。它很方便,因为它允许您使用一个术语
A
来指代相关但不同的事物,而无需为每个事物发明新的术语(例如,类构造函数为
A
,实例类型为
InstanceA
)。但这是令人困惑的,因为它可能会给人一种错误的印象,即这两件事实际上是一件事,或者这两件事之间的关系是名字中固有的,而这只是偶然的


另一方面,当您编写变量声明时

class A { a = 1 }
const B = class extends A { b = 2 };
您只将名为
B
的值引入范围。没有名为
B
的对应类型。如果需要此类类型,则必须自己声明:

type B = InstanceType<typeof B>; 
它知道它构造
B
实例:

type WhatBConstructs = InstanceType<typeof B>;
// type WhatBConstructs = B // this "B" is not an actual type name, btw
type WhatBConstructs=InstanceType;
//类型WhatBConstructs=B//顺便说一句,这个“B”不是实际的类型名
(在这里,我用来探测
B
构造函数的实例类型。)

只是变量声明命名新值,而不是新类型


有一个现有的建议是,当您将类构造函数绑定到变量时,它还应该使命名类型与实例类型相对应。如果要实现这一点,那么当您编写
constb=class扩展A{…}
时,就会出现
B
类型。如果你想看到这种情况发生,你可以去那里给它一个
console.log(x instanceof B,x.constructor.name=='B');//如果未编译为typescript,则true
实际返回“true false”。所以“这在TypeScript和JavaScript中都有效”有点误导。如果编译时返回“true true”,则编译器出错。这在TypeScript中也是
true-false
。这个问题是错误的,这一行可能应该删除。@traktor你的右边,哎呀!该代码被简化为实际有用代码的最小值。有一个稍微不同的情况,我们得到了真的,真的。我将更新以删除或更清楚。谢谢,阅读。不确定是否有效果,但我在OP中输入了一个错误。我用
const B=class扩展了a{/*…*/}
替换了
const B=a
,这会产生相同的错误,这就是原始代码的实际外观。抱歉,回答得太好了,谢谢!是的,那种
B
类型只是IntelliSense显示的东西;由于它是一个类表达式,编译器将
B
显示为“有用的”,这(imo)比仅仅说
(匿名类)
或类似于
实例类型的东西更容易混淆。您通常需要
type B=InstanceType
,它将生成一个在IntelliSense中看起来像
type B=B
,但实际工作的类型。无论如何,我更新了我的答案。