TypeScript - 通用函数的 ReturnType 不起作用

Posted

技术标签:

【中文标题】TypeScript - 通用函数的 ReturnType 不起作用【英文标题】:TypeScript - ReturnType of a generic function not working 【发布时间】:2019-01-15 08:26:55 【问题描述】:

typescript 中有一个名为 ReturnType<TFunction> 的功能,它允许您推断特定函数的返回类型,就像这样

function arrayOf(item: string): string[] 
  return [item]

但是,我在使用泛型函数时遇到了问题:

function arrayOf<T>(item: T): T[] 
  return [item]


type R = ReturnType<typeof arrayOf> // R = []
type R = ReturnType<typeof arrayOf<number>> // syntax error
// etc.

使用来自Typescript ReturnType of generic function 的最佳答案,我已经尝试过:(顺便说一句,这不是重复的,它是不同的,因为解决方案和问题确实适用于这种情况)

function arrayOf<T>(x: T): T[] 
  return [x];


type GenericReturnType<R, X> = X extends (...args: any[]) => R ? R : never;

type N = GenericReturnType<number, <T>(item: T) => T[]>; // N = never

我还尝试了以下方法:

type GenericReturnType<TGenericParameter, TFunction> = TFunction extends (...args: any[]) => infer R ? R : never;

type N = GenericReturnType<number, <T>(item: T) => T[]>; // N = []

还有

type GenericReturnType<TGenericParameter, TFunction> = TFunction extends <T>(...args: any[]) => infer R ? R : never;

type N = GenericReturnType<number, <T>(item: T) => T[]>; // N = []

type GenericReturnType<TGenericParameter, TFunction> = TFunction extends <T extends TGenericParameter>(...args: any[]) => infer R ? R : never;

type N = GenericReturnType<number, <T>(item: T) => T[]>; // N = []

还有这个

type GenericReturnType<TGenericParameter, TFunction> = TFunction extends (arg: TGenericParameter) => infer R ? R : never;

type N = GenericReturnType<number, <T>(item: T) => T[]>; // N = []

还有这个

type GenericReturnType<TGenericParameter, TFunction> = TFunction extends <U extends TGenericParameter>(arg: U) => infer R ? R : never;

type N = GenericReturnType<number, <T>(item: T) => T[]>; // N = []

还有

type x = (<T>(item: T) => T[]) extends <T>(arg: T) => infer R ? R : never // x = []

最后

type x = (<T>(item: T) => T[]) extends (arg: number) => infer R ? R : never // x = []

但它们都没有产生非常想要的number[]类型

所以,我的问题是,在给定泛型参数的类型的情况下,有没有办法创建类似于内置 ReturnType 的东西,它适用于具有泛型参数的函数? (又名上述问题的解决方案)

【问题讨论】:

【参考方案1】:

我遇到了和你一样的问题,经过无数次解决方法都不起作用,我发现了一个有点“黑客”的地方。但是,这可能不适用于所有情况:

类似于马特给出的答案,关键是要有一个虚拟函数,但不重写它。与其编写函数的虚拟重写,不如编写一个返回函数的虚拟用法的虚拟函数。然后,使用ReturnType 获取结果类型:

function arrayOf<T>(item: T): T[] 
    return [item];


const arrayOfNumber = () => arrayOf<number>(1);
type N = ReturnType<typeof arrayOfNumber>;

TS 3.7 开始,除非我没有正确地进行研究,否则在没有找到解决方法的情况下仍然不可能达到预期的结果。希望我们能得到如下所示的东西:

function arrayOf<T>(item: T): T[] 
    return [item];


type N = GenericReturnType<typeof arrayOf>; // N<T>

【讨论】:

【参考方案2】:

如果您遵循指向Getting the return type of a function which uses generics 的链接链,则给定函数的类型参数,而不是当前。给定参数类型,您可以编写一个非泛型虚拟函数来传递这些类型的参数,然后检查其返回类型:

function dummy(n: number)  return arrayOf(n); 
type N = ReturnType<typeof dummy>;

【讨论】:

以上是关于TypeScript - 通用函数的 ReturnType 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript 通用函数 - 为数组应用函数时出现“参数不可分配错误”

Typescript - 具有通用类型函数的索引签名

TypeScript 类型推断 - 函数的通用对象

TypeScript 缩短通用函数调用

TypeScript在静态实现中推断出更通用的类型

用于检查数组中的重复项的通用 Typescript 函数