使用ReturnType<T>
正如您所期望的,函数中返回返回类型。
type F = () => string
//ReturnType<F> === string
此外,正如您所期望的,当使用柯里化(Currying)函数时,返回类型为
type FF = () => () => string
//ReturnType<FF> === () => string
有没有办法创建一个返回最终返回值的泛型类型?即E
type FF = () => () => string
//FinalReturnType<FF> === string
最佳答案
这目前有效(TS 3.7),但 TS 团队无意允许,也没有决定支持它。它可能会在未来版本中崩溃。
type FinalReturnType<T> = {
0: T,
1: T extends (...args: any) => infer R ? FinalReturnType<R> : T,
}[T extends (...args: any) => infer _ ? 1 : 0];
它必须如此奇怪和丑陋,因为目前有一个限制,规定类型只能在嵌套在另一个结构类型(在本例中是一个具有两个键的对象)内时才能调用自身,但随后我们立即提取该属性我们需要从元组中获取。
理想的外观:
如果语言支持这种机制,我认为它会很简单:
type FinalReturnType<T> = T extends (...args: any) => infer R
? FinalReturnType<R>
: T;
换句话说,使用递归定义。如果 T
是一个函数,它会传递函数的返回类型来调用自身。如果不是函数,则返回 T
本身。例如:
FinalReturnType<string> // -> string
这样就终止了递归:当您解开返回函数的所有函数层时,您最终会得到一个非函数。
不幸的是,这是不可能的,会产生错误:
Type alias 'FinalReturnType' circularly references itself.
有一个change to enable recursive type references但它无法实现这种情况。
有an open discussion of more general support for recursion .
目前的情况是,只有在自调用周围添加 []
使其成为一个元组,才能编译我的答案:
type FinalReturnType<T> = T extends (...args: any) => infer R
? [FinalReturnType<R>]
: T;
type t1 = FinalReturnType<string>; // -> string
type F = () => string
type t2 = FinalReturnType<F>; // -> [string]
type FF = () => () => string
type t3 = FinalReturnType<FF>; // -> [[string]]
正如您所看到的,这将结果重新包装在嵌套元组层中,并且您又回到了同样的问题,因为您也无法解开它们。
目前,您可以使用以下技巧:包装具有两个属性的对象,然后通过索引正确的属性立即展开,如本答案顶部所述。但这是偶然启用的,TS 团队不确定他们是否想要支持/鼓励这一点。
关于typescript - 柯里化(Currying)函数的返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59548176/