Typescript 类变量和错误:“指的是一个值,但在这里被用作类型。您的意思是 typeof' ...”。究竟为什么?

2023-11-29

这适用于 Javascript 和 Typescript:

class A  { /* ... */ }
const B = class extends A { /* ... */ }
var x = new B();
console.log(x instanceof B, x.constructor.name); // true B

但是如果我尝试声明类型x as B:

var x: B = new B();

我收到打字稿错误:

“B”指的是一个值,但在这里被用作类型。您指的是“typeof B”吗?

(注意,如果我替换,我也会得到同样的错误const B = class extends A { /* ... */ }简单地const B = A,这就是我最初为了使事情尽可能简单而所做的,但在审查时进行了更新)。

我真的不明白为什么会这样。根据运行时Javascriptx is a B(如上面的console.log所示)。和所有类都是对象无论如何(Typescript 文档本身将类等同于“构造函数对象”)。我猜这只是 Typescript 静态分析的限制 - 它无法弄清楚“B”是一个构造函数对象,就像“A”一样并追踪它的类型?

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


附:我意识到有很多关于SO的问题“Blah 指的是一个值,但在这里被用作类型。您的意思是‘typeof Blah’吗?”,但我找不到像上面那样直接接近它的问答。如果我错过了,抱歉。


当你写的时候class声明如

class A { a = 1 }

在 TypeScript 中,您正在引入范围两个不同的东西两者都被命名为A。其一是value named A,运行时存在的类构造函数。另一个是type named A,对应于类实例的TypeScript接口;此类类型在运行时不存在。

还要注意一个值has一种类型,但它本身并不是一种类型。以及类型A值不是A,因为类构造函数本身不是类的实例)。相反,它具有类型typeof A(用表示TypeScript 的typeof类型查询运算符),这类似于类型new () => A(用构造签名).

事实上,值和类型都已命名A很方便但是很混乱。它很方便,因为它可以让您使用一个术语A指代相关但不同的事物,而不需要您为每个事物发明新的术语(例如,A对于类构造函数,但是InstanceA对于实例类型)。但这很令人困惑,因为它可能会给人一种错误的印象,即这两件事实际上是一件事,或者这两件事之间的关系在某种程度上是名称中固有的,而实际上这只是偶然的。


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

const B = class extends A { b = 2 };

你只是将a纳入范围value named B。没有对应的type named B。如果你想要这样的类型,你必须自己声明它:

type B = InstanceType<typeof B>; 

缺少名为的自动类型B不是因为编译器无法弄清楚B是一个类构造函数。编译器确切地知道什么B is:

// const B: typeof B

它知道它构建了B实例:

type WhatBConstructs = InstanceType<typeof B>;
// type WhatBConstructs = B // this "B" is not an actual type name, btw

(这里我用了the InstanceType<T>实用型探测的类型B其实例类型的构造函数。)

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

现有的建议位于微软/TypeScript#36348它要求当您将类构造函数绑定到变量时,它还应该创建一个与实例类型相对应的命名类型。如果要实施这一点,那么您的B当你写的时候会出现类型const B = class extends A {...}。如果你想看到这种情况发生,你可以去那里给它一个

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Typescript 类变量和错误:“指的是一个值,但在这里被用作类型。您的意思是 typeof' ...”。究竟为什么? 的相关文章

  • 我无法注入带有“!important”规则的样式[重复]

    这个问题在这里已经有答案了 我尝试使用以下代码注入样式 document body style color green important Per CSS 级联引用 http www w3 org TR CSS2 cascade html
  • 如何用js获取一个月的4个星期一?

    我正在构建一个图表 其中 x 轴应该是一个月的四个星期 我只想显示该月的四个星期一 我已经有了currentMonth和currentYear变量 而且我知道如何获取该月的第一天 我所需要的只是将一个月的四个星期一放入数组中 所有这些都在同
  • moment.calendar() 没有时间

    我想使用不带时间的 moment calendar 选项 所以而不是 上周二下午 5 点 我想要 上周二 有人知道 Moment 现在是否有解决方案吗 我找到了这个小提琴http jsfiddle net nawxZ http jsfidd
  • 使用 createReducer 函数时构建用于生产的 Angular+ngrx 8 时出错

    目前我正在尝试使用新的 NgRX 构建 Angular NgRX 8 应用程序creator功能 但是当我构建这个用于生产时 出现以下错误 装饰器中不支持函数调用 但在 reducers 中调用了 createReducer 在开发模式下完
  • 通过 AJAX 发送 XML

    我在 jQuery 中创建了一个 xml 文档 如下所示 var xmlDocument
  • 通过搜索查找下一个文本并突出显示不起作用

    当在搜索框中搜索任何文本时 它可以找到并突出显示正确的文本 但是当搜索下一个 新文本时 它无法找到下一个 新文本 再次搜索时它不起作用 我无法找到问题 这JS below JS button search click function va
  • 使用什么事件来在选择文本框中的值时显示警报消息

    我正在使用 jquery 的自动完成 api 来从数据库中获取名称 但是我想在从显示的文本框中选择名称时显示一条警报消息 我将显示一个图像以便更好地理解 当我输入 S 时 它将显示所有包含 S 的记录 所以问题是 如果我选择例如 Spars
  • JavaScript:参数列表后缺少 )

    这个 JavaScript 产生一个错误 参数列表后缺少 在 firebug 中使用代码 我究竟做错了什么 功能d缺少左括号 answer after 不应该逃避 只需常规报价即可
  • 从 JavaScript 将参数传递给 p:remoteCommand

    我想将值传递给remoteCommand来自 JavaScript 如果这是可能的 我该如何做到这一点以及如何在支持 bean 中接收它们 对的 这是可能的 如何执行此操作取决于 PrimeFaces 版本 你可以在PrimeFaces 用
  • 使用 jQuery 的 javascript 关联数组长度

    我正在使用 javascript 关联数组 例如 var testarray testarray one 1 testarray two 2 testarray three 3 我也在旁边使用jquery 如何使用 jquery 或任何其他
  • 无法从 Twin.macro 中的 Prop 获取值

    您可以在这里查看我正在尝试执行的操作的示例 https codesandbox io s vibrant leaf qj8vz https codesandbox io s vibrant leaf qj8vz 注意 这个特定的例子使用双宏
  • 在js中检测浏览器的最佳方法

    JavaScript 中有很多浏览器检测方法 据我所知 使用navigator userAgent或检测特征 例如XMLHttpRequest 等等 谁能告诉我哪种方法最好 最有效 如果你真的需要知道什么browser他们正在使用 你主要需
  • 如何使用 jQuery UI Sortable 正确相交?

    这是我对 jQuery UI Sortable 进行动画处理的尝试 https codepen io anon pen YdMOXE https codepen io anon pen YdMOXE var startIndex chang
  • 将 ESLint 与 Airbnb 样式和选项卡结合使用 (React.js)

    我正在开发一个 React js 应用程序 并且正在尝试检查我的代码 我将 ESLint 与 Airbnb 风格一起使用 但出现以下错误 src Test jsx 4 2 error Unexpected tab character no
  • select 元素是否具有标准值属性?

    这是一个简单的问题 但我找不到任何参考资料 所以就在这里 假设我有一个选择元素
  • backbone.js:视图中影响集合中不同模型的按钮

    我刚刚开始使用backbone js 到目前为止 我真的很喜欢它 我有这样的事情 ModelA ModelB ViewA ViewB ModelA 持有 ModelB 的集合 如何使用按钮构建模型 B 的视图 单击该按钮会更改集合中下一个
  • 在部分渲染时执行 JavaScript

    我有一些 JavaScript 代码 我想在用户单击其文件夹之一后执行 它会触发 show 操作和 show js erb 从而呈 现部分内容 Show js erb 当用户单击其文件夹之一时触发 如下所示 body append 它成功注
  • 如何修复带有单个道具的括号的 prettier 和 tslint 错误?

    我使用 prettier 和 tslint https github com alexjoverm tslint config prettier https github com alexjoverm tslint config prett
  • 在 Javascript 中创建数组

    我对 javascript 不太熟悉 并且在用 javascript 制作 2d 或者也许我可能需要 3d 数组时遇到了一些麻烦 我目前需要收集 2 条信息 一个 ID 和一个值 因此我创建了以下内容 var myArray var id
  • 开玩笑 setTimeout 不暂停测试

    it has working hooks async gt setTimeout gt console log Why don t I run expect true toBe true 15000 我已经查看了这个答案 Jest 文档和几

随机推荐

Powered by Hwhale