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

TypeScript为函数动态添加getter/setter后访问报TS2339错误的解决思路

可行解决方案

核心思路是利用TypeScript的泛型自动推导能力,捕获动态挂载属性的来源结构,在不硬编码键名、不滥用any的前提下,让TS能识别函数上挂载的动态属性。

具体实现步骤

  • 取消给源对象(示例里的obj)预先标注宽泛的索引签名类型,让TS自动推导对象字面量的具体键名和对应值类型——如果一开始就标注{[key:string]:string},TS会丢失对具体字面量键的识别能力,后续推导就会失效。
  • 保持原有运行时的循环挂载逻辑不变,TypeScript本身无法静态识别Object.defineProperty的运行时副作用,这部分是正常的。
  • 在所有动态属性挂载完成后,给函数做一次精确的类型交叉断言:把原函数的类型,和源对象遍历生成的可读写属性类型做交叉,这部分的键名和值类型完全由TS自动推导,不需要手动硬编码。

示例代码

// 自动推导obj的键为'blah' | 'test',值为string
const obj = {
  blah: "ok",
  test: "yes"
};
// 原函数保持定义
const rawFunc = (a: string): void => {};
// 原有动态挂载逻辑不变
for (const key in obj) {
  Object.defineProperty(rawFunc, key, {
    get() { return obj[key]},
    set(a: string) {
      obj[key] = a;
    }
  });
}
// 类型断言:交叉原函数类型和自动推导的属性类型
const func = rawFunc as typeof rawFunc & {
  [K in keyof typeof obj]: typeof obj[K]
};
// 以下访问都不会再报TS2339错误,且类型完全精确
console.log(func.blah); // 类型推导为string
console.log(func.test); // 类型推导为string

更优雅的封装方式

可以把动态挂载的逻辑封装成泛型工具函数,后续使用时连手动写类型交叉的步骤都可以省略,TS会自动完成类型推导:

function attachPropsFromSource<
  FuncType extends (...args: unknown[]) => unknown,
  SourceType extends Record<string, unknown>
>(
  func: FuncType,
  sourceObj: SourceType
): FuncType & { [K in keyof SourceType]: SourceType[K] } {
  for (const key in sourceObj) {
    Object.defineProperty(func, key, {
      get() { return sourceObj[key] },
      set(value: SourceType[typeof key]) {
        sourceObj[key] = value;
      }
    });
  }
  return func as FuncType & { [K in keyof SourceType]: SourceType[K] };
}
// 使用时完全自动推导类型,无硬编码、无any
const obj = { blah: "ok", test: "yes" };
const func = attachPropsFromSource((a: string): void => {}, obj);
console.log(func.blah); // 正常访问,类型为string

注意事项

  • 不要用as any做类型转换,否则会完全丢失TS的类型检查能力。上面的实现中,所有属性的类型都和源对象保持一致,可正常触发类型校验。
  • 如果你的源对象确实需要支持任意动态字符串键,只需要在交叉类型中补充对应的索引签名即可,比如:
    const func = rawFunc as typeof rawFunc & { [key: string]: string };
    
    这部分依然不需要硬编码具体键名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 16:24:06