You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:05:04