柯里化函数的返回类型
ReturnType of curried function
在函数 return 中使用 ReturnType<T>
,如您所料,return 类型。
type F = () => string
//ReturnType<F> === string
此外,如您所料,当使用柯里化函数时,return 类型是
type FF = () => () => string
//ReturnType<FF> === () => string
有没有办法创建 return 最终 return 的通用类型?即.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
是一个函数,它调用自己传递函数的 return 类型。如果不是一个函数,它 return 就是 T
本身。例如:
FinalReturnType<string> // -> string
这样就终止了递归:当您展开 return 函数的所有函数层时,您最终会得到一个非函数。
不幸的是,这是不可能的,会产生错误:
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 团队不确定他们是否要 support/encourage 这个。
在函数 return 中使用 ReturnType<T>
,如您所料,return 类型。
type F = () => string
//ReturnType<F> === string
此外,如您所料,当使用柯里化函数时,return 类型是
type FF = () => () => string
//ReturnType<FF> === () => string
有没有办法创建 return 最终 return 的通用类型?即.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
是一个函数,它调用自己传递函数的 return 类型。如果不是一个函数,它 return 就是 T
本身。例如:
FinalReturnType<string> // -> string
这样就终止了递归:当您展开 return 函数的所有函数层时,您最终会得到一个非函数。
不幸的是,这是不可能的,会产生错误:
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 团队不确定他们是否要 support/encourage 这个。