我有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.
有没有更优雅的方法来解决这个问题?
答案 0 :(得分:3)
您可以将地图值键入为string
输入并返回A
的构造函数:
type AConstructor = new (name: string) => A;
const classes: { [type: string]: AConstructor } = {
b: B,
c: C,
};