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

TypeScript泛型集合Getter函数类型推断异常问题求助

解决方案:利用泛型索引类型实现类型安全的Getter

要让Getter函数根据传入的键返回对应具体类型,核心是通过泛型约束和索引类型查询,让TypeScript关联键与对应值的类型映射关系。

示例代码实现

先定义基础的Entry类、结构枚举和接口,再改造Collection类:

class Entry<T> {
  constructor(public value: T) {}
}

enum Keys {
  Name = 'name',
  Age = 'age'
}

interface CollectionStructure {
  [Keys.Name]: Entry<string>;
  [Keys.Age]: Entry<number>;
}

// 给Collection添加泛型参数S,约束为包含Entry类型的对象
class Collection<S extends Record<string, Entry<any>>> {
  constructor(public state: S) {}

  // 泛型K限定为S的键,返回值类型为S[K],精准匹配键对应的类型
  getEntry<K extends keyof S>(key: K): S[K] {
    return this.state[key];
  }
}

// 实例化时传入符合结构的state,TypeScript会自动推断泛型类型
const col = new Collection({
  [Keys.Name]: new Entry('Alice'),
  [Keys.Age]: new Entry(30)
});

// 现在getEntry能正确推断类型
const nameEntry = col.getEntry(Keys.Name); // Entry<string>
const ageEntry = col.getEntry(Keys.Age); // Entry<number>

为什么原来的实现不行?

你之前的getEntry方法仅把参数类型设为Keys枚举,但TypeScript无法将这个枚举与state的具体键值类型做关联,只能返回所有可能值的联合类型Entry<string>|Entry<number>。

而通过给Collection添加泛型参数S,并让getEntry的泛型K继承keyof S,TypeScript就能明确知道:传入的键K对应的返回值就是S中该键的具体类型,从而实现精准的类型推断。

变体:固定默认结构

如果你的Collection始终基于CollectionStructure,可以给泛型设置默认值,简化实例化:

class Collection<S extends Record<string, Entry<any>> = CollectionStructure> {
  public state: S = {} as S;

  constructor(initialState?: Partial<S>) {
    if (initialState) Object.assign(this.state, initialState);
  }

  getEntry<K extends keyof S>(key: K): S[K] {
    return this.state[key];
  }
}

// 无需手动指定泛型,直接实例化
const col = new Collection({
  [Keys.Name]: new Entry('Bob'),
  [Keys.Age]: new Entry(28)
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:30:52