作为TypeScript的新手,在实例化子类类型的基类中实现静态工厂的最佳方法是什么。例如,考虑基类中的findAll
方法:
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[]
。
发布于 2017-07-23 06:44:53
为了回答我自己的问题,这是TypeScript中一个众所周知的问题。对于静态方法,多态这一点问题有很长一段时间的讨论。解决方案为下面是
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();
发布于 2017-07-16 01:10:42
您需要将子类型构造函数传递给基类型上的静态函数。
这是因为基类不知道(也不应该)知道要使用哪个子构造函数的子类型。
这是它的外观示例-每个子类型定义自己的静态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();
https://stackoverflow.com/questions/45123761
复制相似问题