我正在使用Typescript构建一个类系统。有一个主要的抽象类Component
,它有一个静态方法create()
。将在子项上调用此方法来构建特定实例
abstract class Component {
static build() {
// some additional logic here, for example, cache to reuse instances
return new this();
}
}
class Button extends Component { }
class Input extends Component {}
Button.build(); // returns Button instance
Input.build(); // returns Input instance
这种方法在Javascript中运行良好,但是Typescript在行new this()
报告错误,说“无法创建抽象类的实例。”
如何解释在派生实例上调用方法的typescript,而不是直接在主抽象类上调用?也许有其他方法可以实现我需要的API?
答案 0 :(得分:3)
this
为typeof Component
,由于Component
是抽象类,new this
不可接受。即使Component
不是抽象的,也不会在子类中正确处理Button.build()
返回类型。
需要通过generic method:
进行一些类型提示abstract class Component {
static build<T = Component>(this: { new(): T }) {
return new this();
}
}
class Button extends Component { }
const button = Button.build<Button>(); // button: Button
答案 1 :(得分:0)
可以在不使用泛型的情况下调用工厂方法。同样要在工厂类中使用类型安全,一些类型转换是必要的。
下面是两个示例类,一个是抽象类,一个是非抽象类:
/* eslint-disable prefer-destructuring, max-classes-per-file */
type Class<T> = new (...args: any[]) => T;
class BaseComponent {
static a = 1;
static build<C extends typeof BaseComponent = typeof BaseComponent>(this: C): InstanceType<C> {
const a = this.a;
return new this() as InstanceType<C>;
}
}
abstract class AbstractComponent {
static a = 1;
static build<T extends AbstractComponent = AbstractComponent>(this: Class<T>): T {
const This = (this as any) as typeof AbstractComponent; AbstractComponent; // To be able to use type safety
const a = This.a;
return new this();
}
}
class AButton extends AbstractComponent {
x = 0;
}
class BButton extends BaseComponent {
x = 0;
}
const aButton = AButton.build();
const bButton = BButton.build();
console.log(aButton.x, bButton.x);