【问题标题】:Typescript define subclass mapping and create subclass at runtimeTypescript 定义子类映射并在运行时创建子类
【发布时间】:2018-05-14 06:04:40
【问题描述】:

我有 3 个类定义 A、B 和 C,其中 B 和 C 都扩展了抽象类 A。

abstract class A {
  public name: string;

  constructor(name: string) {
    this.name = name;
  }

  abstract getName(): string;
}

class B extends A {
  getName(): string {
    return "B: " + this.name;
  }
}

class C extends A {
  getName(): string {
    return "C: " + this.name;
  }
}

我正在尝试在运行时创建抽象类的子类,如下所示。但是它会导致编译器错误:“无法创建抽象类的实例”

const classes: { [type: string]: typeof A } = {
  b: B,
  c: C,
};

function test(type: string, name: string) {
  if (!classes.hasOwnProperty(type)) {
    throw new Error(`Invalid type: ${type}`);
  }
  const _class = classes[type];
  return new _class("name");  // compiler error: Cannot create an instance of abstract class.
}

let x = test("b", "bob");
console.log(x.getName());

如果我将classes 定义更改为{ [type: string]: typeof B | typeof C },它会起作用。

const classes: { [type: string]: typeof B | typeof C } = {
  b: B,
  c: C,
};

function test(type: string, name: string) {
  if (!classes.hasOwnProperty(type)) {
    throw new Error(`Invalid type: ${type}`);
  }
  const _class = classes[type];
  return new _class("name");
}

let x = test("b", "bob");
console.log(x.getName());

但是这样定义会很快增长,例如typeof B | typeof C | typeof D | typeof E | etc. 有没有更优雅的处理方式?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您可以将映射值键入为构造函数,接受string 输入并返回A

    type AConstructor = new (name: string) => A;
    
    const classes: { [type: string]: AConstructor } = {
      b: B,
      c: C,
    };
    

    【讨论】:

      猜你喜欢
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      • 2017-07-08
      • 1970-01-01
      • 2020-01-19
      • 2021-09-01
      • 2021-12-12
      • 2017-11-24
      相关资源
      最近更新 更多