typescript - 如何在方法中使用“this”创建类的新实例?
问题描述
我正在寻找一种this
从类方法中调用 new 的方法。
class Example {
fork() {
return new this();
}
}
const x = new Example().fork(); // instance of example
class Alpha extends Example {}
const x = new Alpha().fork(); // expected instance of Alpha but is example
解决方案
我假设您的意思是您想要调用new this.constructor()
(参见MDN 文档)而不是new this()
,因为类的实例也将是类构造函数的情况非常罕见。在运行时,这就是您所需要的。
不幸的是constructor
,TypeScript 中的 for 输入很乱。有关详细信息,请参阅microsoft/TypeScript#3841,但主要问题是,由于子类构造函数可能需要与其超类构造函数不同的一组参数,如果this.constructor
是强类型,那么许多class
层次结构将无法形成有效的子类型层次结构,因此会违反可替代性。
因此在 TypeScript 中,constructor
仅键入为Function
,因此new this.constructor()
会产生错误:
return new this.constructor(); // error!
// This expression is not constructable.
为了告诉编译器这this.constructor
是一个零参数构造函数,您必须使用这样的类型断言:
class Example {
fork(): this {
return new (this.constructor as new () => this)()
}
}
constructor
或向您的类添加强类型属性声明,如下所示:
class Example2 {
['constructor']: new () => this
fork(): this {
return new this.constructor()
}
}
两种解决方案都适用于您提供的示例用例:
const x = new Example().fork(); // Example
class Alpha extends Example { }
const y = new Alpha().fork(); // Alpha
但是这两种解决方案都不会阻止您调用fork()
其构造函数需要参数的子类的实例
class Blop extends Alpha {
constructor(x: string) {
super();
console.log(x.toUpperCase());
}
}
const z = new Blop("oops").fork(); // error at runtime!!
如果没有对 microsoft/TypeScript#3841 的良好解决方案,我认为这可能是你能得到的最好的解决方案。
推荐阅读
- javascript - 从子组件更新父组件状态
- c# - 使用八位字节流使用 HttpClient 上传二进制文件
- c++ - 在函数中访问 const char *arr[] 的元素
- android - 批量查找无效的 AppIID
- azure-devops - 无法更新 Azure Devops (VSTS) 扩展
- git - Stash 在另一个分支中进行更改并返回
- c# - 数据库中的数据不会加载到数据网格视图上
- node.js - 无法在 Dialogflow Fulfillment(内嵌编辑器)中从 Firestore 获取数据
- spring - Spring - 如何调试以找到spring的自动装配或请求参数的具体用途?
- javascript - 为什么在 foreach 循环中不能在 Typescript 中使用全局变量?