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

TypeScript带泛型的interface如何实现对象属性类型精准推导

TypeScript 泛型配置项精准类型推导解决方案

你之前的写法中,直接使用 InterfaceWithGenerics<SomeDictionary> 时,泛型参数 Key 会直接启用默认值 keyof SomeDictionary 联合类型,导致所有配置项的类型都被拓宽为联合类型,无法根据单个配置的 key 自动收窄类型。


实现步骤

第一步:定义联合类型分发工具

我们可以通过映射类型,将字典的每个key单独生成对应的配置项类型,最终组合为联合类型,原有泛型接口不需要改动:

// 原有泛型接口保持不变
interface InterfaceWithGenerics<
  Dict extends Record<string, any>,
  Key extends keyof Dict = keyof Dict
> {
  key: Key;
  dictValueFormatter: ((key: Key, value: Dict[Key]) => any);
}

// 新增分发工具类型
type DictConfig<Dict extends Record<string, any>> = {
  [Key in keyof Dict]: InterfaceWithGenerics<Dict, Key>
}[keyof Dict]

第二步:使用工具类型声明配置数组

将原来的数组类型从 InterfaceWithGenerics<SomeDictionary>[] 替换为 DictConfig<SomeDictionary>[] 即可:

interface SomeDictionary {
  foo: string;
  bar: number;
  baz: boolean;
}

export const dictConfig: DictConfig<SomeDictionary>[] = [
  {
    key: 'foo',
    // 此时推导的类型为:(key: 'foo', value: string) => any,完全符合预期
    dictValueFormatter: (key, value) => `${key}:${value}`,
  },
  {
    key: 'bar',
    // 此处自动推导:(key: 'bar', value: number) => any
    dictValueFormatter: (key, value) => value.toFixed(2)
  }
]

可选简化写法

如果不想单独声明工具类型,也可以使用辅助函数利用TS泛型推断能力简化写法:

function defineDictConfig<Dict extends Record<string, any>>(
  config: DictConfig<Dict>[]
) {
  return config
}

// 使用时无需额外声明数组类型,只需指定字典泛型即可
export const dictConfig = defineDictConfig<SomeDictionary>([
  {
    key: 'foo',
    dictValueFormatter: (key, value) => `${key}:${value}`
  }
])

原理解释

映射类型会遍历字典的每一个key,为每个key生成对应的独立配置项类型,最终通过索引取值 [keyof Dict] 将所有独立类型组合为联合类型。TypeScript对联合类型的匹配是分发式的,当你给配置项的key赋值为具体字面量时,会自动匹配联合中对应key的类型分支,完成类型收窄,最终得到精准的dictValueFormatter参数类型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:51:02