如何提取TypeScript泛型函数指定类型参数的返回类型?
如何提取泛型函数指定类型参数下的返回类型
嘿,我刚好碰到过类似的问题,来给你详细捋捋解决方案~
首先先回顾下TypeScript 2.8里ReturnType的基础用法,它确实挺实用的,能直接提取普通函数的返回类型:
function foo(e: number): number { return e; } type fooReturn = ReturnType<typeof foo>; // 这里得到的类型是number,完全符合预期
但你遇到的泛型函数场景确实会踩坑,直接尝试的几种写法要么得到不符合预期的{},要么直接报语法错误:
function foo<T>(e: T): T { return e; } type fooReturn = ReturnType<typeof foo>; // 结果是{},不是我们想要的泛型返回类型 type fooReturn = ReturnType<typeof foo<number>>; // 语法错误,TypeScript不支持这种写法 type fooReturn = ReturnType<(typeof foo)<number>>; // 同样语法错误
那该怎么正确提取泛型函数在指定类型参数下的返回类型呢?这里有几种靠谱的方案:
方案1:自定义辅助工具类型
我们可以借助条件类型的infer关键字,定义一个能接收泛型函数和目标类型参数的辅助类型:
function foo<T>(e: T): T { return e; } // 通用版辅助类型:支持任意单泛型参数的函数 type ReturnTypeWithGeneric<Fn, T> = Fn extends <U>(arg: U) => infer R ? (U extends T ? R : never) : never; // 使用方式:指定我们要的类型参数number type FooNumberReturn = ReturnTypeWithGeneric<typeof foo, number>; // 得到number类型
如果你的泛型函数有多个参数,也可以针对性调整辅助类型的结构,确保准确匹配。
方案2:利用类型断言绑定泛型参数
我们可以先创建一个绑定了目标类型参数的函数类型,再用ReturnType提取:
function foo<T>(e: T): T { return e; } // 把foo断言为绑定了number类型的函数 const fooNumber = foo as (arg: number) => number; type FooNumberReturn = ReturnType<typeof fooNumber>; // 得到number类型
这种写法比较直观,适合简单的泛型函数场景。
方案3:TypeScript 4.7+的简洁写法
在TypeScript 4.7及以上版本,我们可以通过嵌套条件类型直接实现,写法更紧凑:
function foo<T>(e: T): T { return e; } type GetFooReturnType<T> = typeof foo extends <U>(arg: U) => U ? ReturnType<(arg: T) => T> : never; type FooNumberReturn = GetFooReturnType<number>; // 得到number类型
这些方法都能帮你准确提取泛型函数在指定类型参数下的返回类型,你可以根据自己的TS版本和场景选择合适的写法~
内容的提问来源于stack exchange,提问作者samfrances




