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

TypeScript中如何实例化泛型类?两种场景实现方案

TypeScript中泛型类实例的创建方法(两种场景)

TypeScript里创建泛型类实例的核心问题是类型擦除——编译后泛型类型信息会被移除,没法直接通过new T()创建实例,必须把类型的构造函数显式传入。下面分两种场景解决你的问题:

场景1:编译时已知类型参数

先修正你的Buz泛型类写法,泛型约束要用extends而非implements,同时要接收对应类型的构造函数作为参数(因为没法直接用T来实例化):

interface ITheValue {
  TheValue: string;
}

class Foo implements ITheValue {
  TheValue: string;
  constructor(val: string) {
    this.TheValue = val;
  }
}

class Bar implements ITheValue {
  TheValue: string;
  constructor(val: string) {
    this.TheValue = val;
  }
}

// 修正泛型类:约束T为ITheValue的实现类,同时接收T的构造函数
class Buz<T extends ITheValue> {
  Thing: T;

  // 构造函数接收两个参数:T的构造器、初始化值
  constructor(private ctor: new (val: string) => T, val: string) {
    this.Thing = new ctor(val);
  }

  getTheValue(): string {
    return this.Thing.TheValue;
  }
}

现在编译时已知类型(比如Foo),直接传入构造器就能创建实例:

function runKnownType(theValue: string): string {
  // 直接传入Foo的构造函数作为第一个参数
  const buz = new Buz(Foo, theValue);
  return `The value is: ${buz.getTheValue()}.`;
}

// 调用示例
console.log(runKnownType("foo test value")); // 输出:The value is: foo test value.

场景2:通过字符串值指定类型名称

这种情况需要先建立字符串到类构造器的映射表,根据传入的字符串找到对应的构造函数,再创建泛型实例:

// 建立字符串到构造器的映射
const typeMap: Record<string, new (val: string) => ITheValue> = {
  Foo: Foo,
  Bar: Bar
};

function runByTypeName(whichOne: string, theValue: string): string {
  // 根据字符串获取对应的构造器,先做合法性检查
  const ctor = typeMap[whichOne];
  if (!ctor) {
    throw new Error(`Unknown type: ${whichOne}`);
  }

  // 传入构造器创建泛型实例
  const buz = new Buz(ctor, theValue);
  return `The value is: ${buz.getTheValue()}.`;
}

// 调用示例
console.log(runByTypeName("Bar", "bar test value")); // 输出:The value is: bar test value.

关键说明

  1. 为什么不能直接new T()?因为TypeScript的泛型是编译时语法糖,编译成JS后T会被替换成any或对应的约束类型,没有实际的构造函数信息,必须显式传入构造器。
  2. 泛型约束要用extends:对于类/接口的约束,TypeScript里泛型语法是T extends 类型,而不是implements。
  3. 字符串映射的安全性:如果要更严谨,可以把whichOne的类型定义为keyof typeof typeMap,这样TypeScript会在编译时检查传入的字符串是否合法:
function runByTypeName(whichOne: keyof typeof typeMap, theValue: string): string {
  // ... 内部逻辑不变
}

内容的提问来源于stack exchange,提问作者Richard Barraclough

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:50:28