如何创建TypeScript工具类型推断索引访问类型中使用的键?
如何创建工具类型推断索引访问使用的键
问题描述
需要实现一个工具类型Helper,从泛型函数的返回值(索引访问类型)中推断出对应的键。示例如下:
type X = { foo: string, bar: boolean } type Fn = <T extends X>(value: T) => T["foo"] type Helper<T> = ??? type Result = Helper<Fn> // 期望得到 "foo"
可行的解决方案
可以直接在条件类型中匹配泛型函数的返回值索引位置来提取键,实现代码如下:
type X = { foo: string, bar: boolean } type Fn = <T extends X>(value: T) => T["foo"] type Helper<F> = F extends <T extends infer _U>(value: T) => T[infer K] ? K : never type Result = Helper<Fn> // 结果为 "foo"
原理说明
- 核心逻辑是在匹配泛型函数类型时,直接在返回值的索引访问表达式
T[infer K]里用infer提取键K。TypeScript能直接识别出这个K就是访问T时使用的索引键。 - 泛型参数
T的约束infer _U(下划线表示该值无需使用)用来匹配原函数中T extends X的泛型约束,保证类型匹配的准确性。
原写法失效原因
你之前尝试的写法:
type Helper<Fn> = Fn extends (value: infer T) => infer R ? R extends T[keyof T] ? T[keyof T] : never : never
问题在于:
- 推断出的
R是T["foo"],但T是泛型类型参数,TypeScript无法从属性值类型反向推断对应键——不同键可能对应相同属性值类型,这种反向关联没有唯一解。 - 即便匹配
R extends T[keyof T],最终返回的T[keyof T]是属性值的联合类型(比如string | boolean),并非需要的键名。
扩展场景
如果函数返回多个索引访问的联合类型,Helper也能正确推断出对应的键联合:
type Fn2 = <T extends X>(value: T) => T["foo"] | T["bar"] type Result2 = Helper<Fn2> // "foo" | "bar"
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

