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

TypeScript中如何实例化泛型抽象工厂的泛型类型?

解决TypeScript泛型抽象工厂的重复代码问题

首先明确:你最初的代码无法运行,核心原因是TypeScript编译后会擦除泛型类型信息,运行时new T(attribute)里的T没有对应的构造函数实体,必然抛出错误。

下面提供两种重构方案,彻底消除重复的工厂类代码:

方案一:改造泛型工厂类,注入构造函数

让抽象工厂类接收Item的构造函数作为实例依赖,在create方法中复用该构造函数创建实例:

// 定义Item构造函数的类型约束,保证类型安全
type ItemConstructor<T extends Item> = new (attribute: ConstructorParameters<typeof T>[0]) => T;

abstract class GenericItemFactory<T extends Item> {
  protected constructor(private readonly itemCtor: ItemConstructor<T>) {}

  create(attribute: ConstructorParameters<typeof this.itemCtor>[0]): T {
    return new this.itemCtor(attribute);
  }
}

// 具体工厂只需传入构造函数,无需重写create
class ItemAFactory extends GenericItemFactory<ItemA> {
  constructor() {
    super(ItemA);
  }
}

class ItemBFactory extends GenericItemFactory<ItemB> {
  constructor() {
    super(ItemB);
  }
}

每个具体工厂类仅需一行构造函数代码,完全消除了重复的create方法逻辑。

方案二:用高阶函数直接生成工厂实例(更简洁)

如果连工厂子类都不想定义,可以用一个工具函数直接生成带有create方法的工厂对象,彻底省去所有工厂类:

type ItemConstructor<T extends Item> = new (attribute: ConstructorParameters<typeof T>[0]) => T;

function createItemFactory<T extends Item>(itemCtor: ItemConstructor<T>) {
  return {
    create: (attribute: ConstructorParameters<typeof itemCtor>[0]): T => {
      return new itemCtor(attribute);
    }
  };
}

// 直接生成各Item的工厂实例,新增Item仅需添加一行
const items = {
  itemA: createItemFactory(ItemA),
  itemB: createItemFactory(ItemB),
  itemC: createItemFactory(ItemC),
  // ...后续新增项
};

这种方式无需定义GenericItemFactory类,所有重复逻辑都封装在createItemFactory函数中,是代码量最少的实现方式。

补充:优化类型安全(替换any)

上述代码使用ConstructorParameters工具类型自动推导构造函数的参数类型,避免了any的滥用,让整个工厂体系的类型检查更严格。比如ItemA的构造函数若需要特定类型的attribute,TypeScript会自动在create方法中提示对应的参数类型。

内容的提问来源于stack exchange,提问作者Joshua Ohana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:18:18