如何在动态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_
相关产品推荐
相关产品推荐

