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

如何在动态Record中推断泛型子类型?

你的实现存在类型精度问题,不可行

原代码的核心问题在于ParameterDictionary的定义:

type ParameterDictionary = Record<
  string,
  ParameterDescription<string | number | boolean>
>;

当你把config标注为这个类型时,TypeScript会将config的键宽泛化为通用的string,同时每个值的类型也被拓宽为ParameterDescription<string | number | boolean>,丢失了foo对应字符串、bar对应数字这类具体的类型信息。这会导致get函数无法准确推断出对应键的返回类型——实际编译时a、b、c的类型都会是string | number | boolean,而不是你期望的具体类型。

改进方案:让类型自动推断,避免宽泛标注

要实现你想要的动态映射+精确类型推断,不需要显式声明接口,只需要让config的类型自动推断,同时调整get函数的泛型定义:

type ParameterDescription<T> = {
  default: T;
};

// 不要给config标注宽泛的ParameterDictionary,让TypeScript自动推断具体类型
// 可选:添加`as const`进一步锁定字面量类型,避免值被自动拓宽(比如数字1不会变成number)
const config = {
  foo: { default: "test" },
  bar: { default: 1 },
  baz: { default: true },
} as const;

// 重载get函数,分别处理存在的键和不存在的键
function get<T extends Record<string, ParameterDescription<any>>, K extends keyof T>(
  config: T,
  key: K
): T[K]['default'];
function get<T extends Record<string, ParameterDescription<any>>>(
  config: T,
  key: string
): undefined;
function get<T extends Record<string, ParameterDescription<any>>>(config: T, key: string) {
  const param = config[key];
  return param ? param.default : undefined;
}

const a = get(config, "foo"); // 类型:"test"(如果用了as const)或string
const b = get(config, "bar"); // 类型:1(如果用了as const)或number
const c = get(config, "baz"); // 类型:true(如果用了as const)或boolean
const d = get(config, "boz"); // 类型:undefined

关键调整点:

  • 移除config的ParameterDictionary标注,让TypeScript自动从对象字面量推断出每个键对应的具体ParameterDescription类型。
  • 用T[K]['default']直接提取对应键的默认值类型,比自定义ParameterSubType更直观且准确。
  • 通过函数重载处理存在/不存在的键,确保传入不存在的键时返回类型为undefined。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:00:14