抽象类

时间:2018-03-29 23:42:22

标签: typescript oop

我正在使用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

Same code in TS Playground

这种方法在Javascript中运行良好,但是Typescript在行new this()报告错误,说“无法创建抽象类的实例。”

如何解释在派生实例上调用方法的typescript,而不是直接在主抽象类上调用?也许有其他方法可以实现我需要的API?

2 个答案:

答案 0 :(得分:3)

thistypeof 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);