TypeScript中如何将子类构造函数数组类型化为接口/抽象类?
当然可行!不过要注意构造函数类型的正确写法
你存的是类的构造函数(不是类的实例),所以不能直接把数组类型指定为Section[]或AbstractSection[]——这些是实例类型。TypeScript里需要用构造签名来定义“能生成对应接口/抽象类实例的构造函数”类型。
下面分两种情况给你具体示例:
一、针对接口的场景
假设你的接口是Section,实现它的子类构造函数数组,类型可以定义为Array<new () => Section>,意思是“所有能无参构造出Section实例的构造函数”:
export interface Section { somePropName: string; } class SectionSubclass1 implements Section { somePropName = "subclass1"; } class SectionSubclass2 implements Section { somePropName = "subclass2"; } // 替换any[],用正确的构造函数数组类型 const arrayOfClasses: Array<new () => Section> = [SectionSubclass1, SectionSubclass2]; // 类型安全的实例化 const firstInstance = new arrayOfClasses[0](); console.log(firstInstance.somePropName); // 编辑器会自动提示这个属性,类型完全安全
如果你的子类构造函数需要参数,只需要调整构造签名的参数即可,比如:Array<new (prop: string) => Section>——表示所有接受一个string参数、返回Section实例的构造函数。
二、针对抽象类的场景
抽象类的逻辑和接口类似,只是抽象类本身不能被实例化,但子类可以。数组类型同样用构造签名来定义:
export abstract class AbstractSection { somePropName: string; constructor(initialProp: string) { this.somePropName = initialProp; } } class SectionSubclass1 extends AbstractSection { constructor() { super("subclass1"); } } class SectionSubclass2 extends AbstractSection { constructor() { super("subclass2"); } } // 这里子类构造函数无参,所以类型是new () => AbstractSection const arrayOfClasses: Array<new () => AbstractSection> = [SectionSubclass1, SectionSubclass2]; // 如果子类需要传递参数给父类,比如: // class SectionSubclass3 extends AbstractSection { // constructor(prop: string) { // super(prop); // } // } // 那数组类型就要改成:Array<new (prop: string) => AbstractSection>
额外提示
如果你的子类构造函数签名不一致(有的无参,有的有参),可以用更宽泛的构造签名来兼容,比如Array<new (...args: any[]) => Section>,但这样会丢失部分类型安全,建议尽量统一子类的构造函数签名,这样既能保证类型安全,代码也更规整。
内容的提问来源于stack exchange,提问作者BBaysinger
相关产品推荐
相关产品推荐

