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

如何为类中的动态对象/Record设置正确的TypeScript类型?

实现可动态追加属性的TypeScript服务类

要让Services实例支持动态添加属性且保留完整类型提示,核心是利用泛型类结合类型扩展机制,让TypeScript实时跟踪已添加的属性类型。以下是具体实现方案:

1. 基础泛型类实现

class Services<T extends Record<string, unknown> = {}> {
  // items类型与泛型T绑定,彻底避免any
  items: T = {} as T;

  // add方法通过泛型K、V扩展当前类的泛型类型
  add<K extends string, V>(key: K, value: V): Services<T & Record<K, V>> {
    (this.items as T & Record<K, V>)[key] = value;
    // 将属性直接挂载到实例,支持services.test这种直接访问方式
    (this as any)[key] = value;
    return this as Services<T & Record<K, V>>;
  }

  // 索引签名允许实例直接访问动态添加的属性
  [key: string]: unknown;
}

// 示例服务类
class TestService {
  greet() {
    console.log("Hello from TestService");
  }
}

2. 使用示例

// 初始实例类型为Services<{}>
const services = new Services();

// 添加test属性后,实例类型自动扩展为Services<{ test: TestService }>
const updatedServices = services.add('test', new TestService());

// 两种访问方式都有完整类型提示
updatedServices.items.test.greet(); // ✅ 类型提示正常
updatedServices.test.greet(); // ✅ 实例直接访问也有提示

// 继续添加新属性,类型会进一步扩展
const finalServices = updatedServices.add('logger', { log: (msg: string) => console.log(msg) });
finalServices.logger.log("Hi"); // ✅ 新属性同样有类型提示

3. 无需重新赋值的进阶版本

如果希望services变量本身自动更新类型(不用每次赋值给新变量),可以用TypeScript的断言函数实现:

class Services<T extends Record<string, unknown> = {}> {
  items: T = {} as T;

  // 断言函数告诉TS:调用add后,当前实例类型已扩展
  add<K extends string, V>(key: K, value: V): asserts this is Services<T & Record<K, V>> {
    (this.items as T & Record<K, V>)[key] = value;
    (this as any)[key] = value;
  }

  [key: string]: unknown;
}

// 使用断言函数的版本
const services = new Services();
services.add('test', new TestService());
services.test.greet(); // ✅ 无需重新赋值,直接有类型提示

关键细节说明

  • 泛型跟踪类型:Services<T>中的泛型T始终记录已添加的所有属性类型,每次add都会返回扩展了新属性的类型实例。
  • 避免any类型:items的类型绑定到T,而非宽泛的object或Record<string, any>,确保所有值的类型都被TS正确推断。
  • 实例直接访问:通过索引签名和直接挂载属性,支持services.test这种直观的访问方式,而非只能通过items层级访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:33:24