基于参数对象值类型推断函数返回类型的TypeScript问题
解决方案
可以通过嵌套条件类型区分「宽泛string类型」和「具体字符串字面量联合类型」两种场景,实现符合预期的类型推断:
const getValue = <T extends string>(key: T) => <O extends string extends T ? Record<string, unknown> : { [K in T]: unknown }>(obj: O): string extends T ? O[keyof O] | undefined : O[T] => { return obj[key as keyof O]; };
效果验证
1. 字符串字面量联合类型key
const key = "A" as "A" | "B" | "C"; // 正确推断返回类型:number | boolean const value = getValue(key)({ A: 2, B: 1, C: true });
2. 宽泛string类型key
// 正确推断返回类型:number | boolean | undefined const otherValue = getValue(key as string)({ A: 2, B: 1, C: true });
实现逻辑说明
- 用
string extends T判断当前T是宽泛string还是具体字面量联合:- 若
string extends T为真(即T是宽泛string):- 允许对象为任意字符串键的普通对象(
Record<string, unknown>) - 返回类型设为对象所有值类型的联合 +
undefined(兼容key不存在的情况)
- 允许对象为任意字符串键的普通对象(
- 若
string extends T为假(即T是具体字面量联合):- 强制对象必须包含联合类型的所有键(
{ [K in T]: unknown }) - 返回类型为对应键的值类型联合(
O[T])
- 强制对象必须包含联合类型的所有键(
- 若
- 函数体中
key as keyof O是必要的类型断言,避免TypeScript对宽泛string场景下的键存在性检查报错。
内容的提问来源于stack exchange,提问作者bigbeno37
相关产品推荐
相关产品推荐

