如何指定泛型函数参数并获取TypeScript函数返回类型
问题描述
有一个包含泛型函数的对象:
const someObject = { someFunction: <T extends { name: string }>(value: T) => value.name as T["name"], };
想要传入更具体的T类型时获取该函数的返回类型,但直接提取函数类型后尝试传入泛型参数会报错Type 'Fn' is not generic,导致后续类型推导失败:
type Fn = (typeof someObject)["someFunction"]; type Input = { name: "john" }; type SpecificFn = Fn<Input>; // 报错 // 期望SpecificFn为`(x: {name:"john"})=>"john"` type Output = ReturnType<SpecificFn>; // 期望类型为"john"
目前已知一种借助常量辅助的实现方案,但希望仅通过类型系统完成需求:
const helper = null as unknown as Fn; type SpecificFn1 = (typeof helper<Input>); type Output1 = ReturnType<SpecificFn1>; // 得到"john"
解决方案
方法1:用工具类型转发泛型实例化
定义一个工具类型,接收泛型函数类型和具体参数类型,返回实例化后的函数类型:
type InstantiateGenericFn<GenericFn extends <T>(...args: any) => any, T> = GenericFn extends <U>(value: U) => infer Return ? (value: T) => Return extends U["name"] ? T["name"] : Return : never; type Fn = (typeof someObject)["someFunction"]; type Input = { name: "john" }; type SpecificFn = InstantiateGenericFn<Fn, Input>; // (value: { name: "john"; }) => "john" type Output = ReturnType<SpecificFn>; // "john"
方法2:直接推导返回类型(跳过函数实例化)
如果只需要最终的返回类型,可以直接构造调用场景推导结果,无需先实例化函数类型:
type Input = { name: "john" }; type Output = ReturnType< (typeof someObject)["someFunction"] extends <T>(v: T) => infer R ? (v: Input) => R : never >; // "john" // 更简洁的写法: type Output2 = (typeof someObject)["someFunction"] extends <T>(v: T) => infer R ? R extends T["name"] ? Input["name"] : R : never; // "john"
方法3:TypeScript 4.7+ 原生泛型类型实例化(推荐)
从TypeScript 4.7开始,支持直接对提取的泛型函数类型进行泛型参数实例化,写法非常直观:
type Fn = typeof someObject.someFunction; type Input = { name: "john" }; type SpecificFn = Fn<Input>; // (value: { name: "john"; }) => "john" type Output = ReturnType<SpecificFn>; // "john"
如果你的TS版本低于4.7,这种写法会报错,需要升级到对应版本。
内容的提问来源于stack exchange,提问作者TheBlueOne
相关产品推荐
相关产品推荐

