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

TypeScript中如何基于泛型生成运行时可用的键枚举

问题根因

TypeScript的泛型仅在编译阶段生效,编译完成后所有泛型标记会被完全擦除。原实现中key: T本质是声明了一个与T类型结构一致的普通属性,运行时不会自动将T的属性名替换为枚举键值,这也是代码能通过编译校验、但运行时拿到Employee实例默认属性值的核心原因。

实现方案

我们需要同时兼顾两层需求:编译阶段的智能提示、运行时的键值返回,核心思路是将key属性设计为键名代理对象,分别在类型层、运行层做适配:

步骤1:定义键代理的基础类型

先构造一个映射类型,将传入类型T的所有属性键,映射为对应的键名字面量类型,既保证智能提示的完整性,又让类型校验更精准:

// 将T的每个属性键映射为对应的字面量类型,避免宽泛的string类型
type KeyProxy<T> = {
  [K in keyof T]: K
};

针对Employee类,这个类型的实际结构会映射为{ name: 'name'; department: 'department' },访问对应属性时拿到的是精确的字面量类型,而非宽泛的字符串。

步骤2:重构Person类

使用Proxy实现运行时的键名代理,让任何对key属性的访问,都直接返回被访问的属性名字符串;同时通过类型标注匹配上面定义的KeyProxy结构,保证类型提示不丢失:

class Person<T> {
  private _key: KeyProxy<T>;

  // 对外暴露key访问器,类型严格匹配KeyProxy<T>结构
  public get key(): KeyProxy<T> {
    return this._key;
  }

  constructor() {
    // 初始化Proxy代理:所有属性访问直接返回属性名本身
    this._key = new Proxy({} as KeyProxy<T>, {
      get(_, propertyKey) {
        return propertyKey.toString();
      }
    });
  }

  // 实现业务需要的value方法,接收传入的键字符串完成对应逻辑
  public value(key: keyof T) {
    // 可根据业务补充键值校验、取值等逻辑
    console.log(`当前传入的键值为:${key}`);
  }
}

步骤3:实现通用createPerson工厂方法

通过泛型推断的方式,从传入的类构造器中自动提取T的类型,不需要手动指定泛型参数:

// 定义通用类构造器签名
type Constructor<T> = new (...args: any[]) => T;

function createPerson<T>(type: Constructor<T>) {
  // 泛型自动从传入的构造器中推断出T的类型
  const person = new Person<T>();
  return person;
}
效果验证

针对原始的Employee类场景做验证:

class Employee {
  name = "Ujjwal Gupta";
  department = "Engineering";
}

// 无需手动传入泛型参数,自动推断类型
const person = createPerson(Employee);

// 编译阶段智能提示会自动列出name、department两个可用键
console.log(person.key.name); // 运行时输出字符串"name",符合预期
console.log(person.key.department); // 运行时输出字符串"department"
person.value(person.key.name); // 成功传入"name"字面量作为参数,类型校验完全通过
方案优势
  • 类型完整性:基于keyof映射的类型定义,完全保留传入类型的所有键提示,访问不存在的键时会直接触发编译错误
  • 运行时正确性:Proxy代理的逻辑会直接返回被访问的属性名字符串,不会出现类实例默认属性值的干扰
  • 使用便捷性:通用工厂方法支持传入任意业务类,自动匹配对应的键提示能力,无需重复编写适配代码

内容的提问来源于stack exchange,提问作者Ujjwal Kumar Gupta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 00:36:00