使用TypeScript从基类中的静态方法实例化子类
作为TypeScript的新手,在实例化子类类型的基类中实现静态工厂的最佳方法是什么。例如,在基本模型类中考虑<代码> FUNDALL < /代码>方法:使用TypeScript从基类中的静态方法实例化子类,typescript,Typescript,作为TypeScript的新手,在实例化子类类型的基类中实现静态工厂的最佳方法是什么。例如,在基本模型类中考虑 FUNDALL < /代码>方法: class BaseModel { static data: {}[]; static findAll() { return this.data.map((x) => new this(x)); } constructor(readonly attributes) { } } class Model extends
class BaseModel {
static data: {}[];
static findAll() {
return this.data.map((x) => new this(x));
}
constructor(readonly attributes) {
}
}
class Model extends BaseModel {
static data = [{id: 1}, {id: 2}];
constructor(attributes) {
super(attributes);
}
}
const a = Model.findAll(); // This is BaseModel[] not Model[]
这将返回
BaseModel[]
而不是Model[]
您需要将子类型构造函数传递给基类型上的静态函数
这是因为基类不知道(也不应该)知道子类型,以知道要使用哪个子构造函数
这是一个可能的示例-每个子类型定义自己的静态findAll()
方法,该方法调用父类上的标准行为,传递数据和构造函数供父类使用:
class BaseModel {
static data: {}[];
static _findAll<T extends BaseModel>(data: any[], Type): T[] {
return data.map((x) => new Type(x));
}
constructor(readonly attributes) {
}
}
class Model extends BaseModel {
static data = [{ id: 1 }, { id: 2 }];
constructor(attributes) {
super(attributes);
}
static findAll() {
return BaseModel._findAll(this.data, this);
}
}
const a = Model.findAll();
类基本模型{
静态数据:{}[];
静态_findAll(数据:任意[],类型):T[]{
返回data.map((x)=>新类型(x));
}
构造函数(只读属性){
}
}
类模型扩展了BaseModel{
静态数据=[{id:1},{id:2}];
构造函数(属性){
超级(属性);
}
静态findAll(){
返回BaseModel.\u findAll(this.data,this);
}
}
常数a=Model.findAll();
回答我自己的问题,这是TypeScript中一个众所周知的问题。Github问题有很长的讨论时间。解决办法如下:
导出类型StaticThis={new():T};
导出类基{
静态创建(this:StaticThis){
constthat=newthis();
归还;
}
baseMethod(){}
}
导出类派生扩展基{
derivedMethod(){}
}
//工作
Base.create().baseMethod();
派生的.create().baseMethod();
//也行
派生的.create().derivedMethod();
//不工作(正常)
Base.create().derivedMethod();
还有更好的方法。谢谢,我不知道静态函数的新this()
功能我无法描述我花了多少时间来解决这个问题。谢谢dude@Tristan我刚刚遇到了一个棘手的情况,因为Base
同时有一个通用的。。。想想看。。。出于好奇,指定T扩展Base的目的是什么?我喜欢这个。当构造函数不接受参数时,它会工作,创建的更通用的签名是:staticcreate(this:{new(…args:any[]):t;}
export type StaticThis<T> = { new (): T };
export class Base {
static create<T extends Base>(this: StaticThis<T>) {
const that = new this();
return that;
}
baseMethod() { }
}
export class Derived extends Base {
derivedMethod() { }
}
// works
Base.create().baseMethod();
Derived.create().baseMethod();
// works too
Derived.create().derivedMethod();
// does not work (normal)
Base.create().derivedMethod();