在TypeScript

时间:2018-01-18 00:00:19

标签: typescript inheritance abstract-class typescript2.6

我在TypeScript 2.6中编写了一些图形代码,而且我在继承和通用代码方面遇到了一个小障碍:

abstract class Series { /**/ }

class LineSeries    extends Series { /**/ }
class BarSeries     extends Series { /**/ }
class ScatterSeries extends Series { /**/ }

class Chart {
  private seriesArray: Series[] = [];

  constructor(series: Series[]) {
    let seriesType: typeof Series = null;

    switch (series.SeriesType) {
      case SeriesType.LineSeries:
        seriesType = LineSeries;
        break;
      case SeriesType.BarSeries:
        seriesType = BarSeries;
        break;
      case SeriesType.ScatterSeries:
        seriesType = ScatterSeries;
        break;
      default:
        throw "Unsupported series type";
    }

    for (let i = 0; i < series.length; i++)
      this.SeriesArray.push(new seriesType());
  }
}

我希望上面的代码构造一个派生自Series的新对象,其中最后一行的构造函数来自运行时分配的类型值。我遇到的问题是Series是抽象的,所以我无法实例化它,但是我永远不会将值typeof Series赋给series变量。 (但TypeScript并不知道)。

我想到了一些解决方案,但没有一个特别优雅。一种是简单地从abstract中删除Series修饰符,并可选择输入一些代码,以便在实例化时抛出异常。另一种解决方案是将seriesType的定义更改为:

let seriesType: (typeof LineSeries | typeof BarSeries | typeof ScatterSeries) = null;

但是每次添加新类型的系列时我都需要维护这个列表。我知道我能做到,例如:

type DerivedSeries = (typeof LineSeries | typeof BarSeries | typeof ScatterSeries);

然后

let seriesType: DerivedSeries = null;

但如果有的话,这并没有太大的改善。

我可以告诉TypeScript seriesType类型为Series,但是还必须是可实例化的子类型吗?即表达式seriesType = Series;应该抛出编译时错误,而不是new seriesType();

由于

1 个答案:

答案 0 :(得分:4)

实例化从抽象类派生的类的最简单方法是使用new()方法定义对象类型:

abstract class AbstractClass { /**/ }

class DerivedClassA extends AbstractClass { /**/ }
class DerivedClassB extends AbstractClass { /**/ }

const classCtors: Array<{ new(): AbstractClass }> = [
    DerivedClassA,
    DerivedClassB
];

for (const ctor of classCtors) {
    const instance = new ctor();
}