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

TypeScript如何为类动态生成的get方法实现强类型校验

链式调用add方法的强类型实现

核心通过TS映射类型动态生成getXxx格式的方法签名,再通过add方法返回交叉类型累加已添加的方法定义:

// 通用工具类型:将对象的键转换为 `getXxx` 格式的无参方法,返回对应值的类型
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
};

class App<ObjList extends Record<string, any>> {
  private objects = new Map<keyof ObjList, any>();

  add<T extends keyof ObjList>(name: T, value: ObjList[T]): this & Getters<Pick<ObjList, T>> {
    this.objects.set(name, value);
    (this as any)[`get${String(name)}`] = () => value;
    return this as this & Getters<Pick<ObjList, T>>;
  }
}

使用示例:

const app = new App<{ Test: string, Test2: number }>()
  .add('Test', 'this is my test string')
  .add('Test2', 5);

// TS可正确识别方法存在,返回值类型推导为string
app.getTest();
// TS可正确识别返回值类型推导为number
app.getTest2();

构造函数直接初始化的强类型实现

通过TS的声明合并特性,直接将生成的getter方法类型合并到类的实例类型中:

type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
};

// 接口和类同名,自动合并类型,将getter方法注入到实例类型中
interface App<ObjList extends Record<string, any>> extends Getters<ObjList> {}

class App<ObjList extends Record<string, any>> {
  private objects: Map<keyof ObjList, any>;

  constructor(initObjects: ObjList) {
    this.objects = new Map(Object.entries(initObjects));
    Object.entries(initObjects).forEach(([key, value]) => {
      (this as any)[`get${key}`] = () => value;
    });
  }
}

使用示例:

// 无需手动传入泛型,TS可自动根据入参推导类型
const inst = new App({
  Test: 'this is my test string',
  Test2: 5
});

// TS正确识别返回值类型为string
inst.getTest();
// TS正确识别返回值类型为number
inst.getTest2();

注意事项

  • 以上实现依赖TypeScript 4.1及以上版本,用到了模板字面量类型、键重映射的特性
  • 如果存在非字符串类型的键,可对Getters工具类型做扩展兼容处理

内容的提问来源于stack exchange,提问作者Adam Baranyai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 10:27:02