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

时间:2018-08-08 07:05:32

标签: javascript typescript types

打字稿中有一个名为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的东西的功能,该功能适用​​于带有通用参数的函数? (也可以解决上述问题)

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

我遇到了与您相同的问题,并且在无数种解决方法不起作用之后,我发现了一个“ hack”。但是,这可能不适用于所有情况:

类似于Matt给出的答案,重点是具有虚拟功能,但无需重写它。不用编写函数的伪重写,而是编写返回函数的伪用法的伪函数。然后,使用function arrayOf<T>(item: T): T[] { return [item]; } const arrayOfNumber = () => arrayOf<number>(1); type N = ReturnType<typeof arrayOfNumber>; 获取结果类型:

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

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

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

    using(ApplicationDbContext db=new ApplicationDbContext())
    {
          var users = (from user in db.Users
                       from roles in user.Roles
                       join role in db.Roles
                       on roles.RoleId equals role.Id 
                       select new
                       {
                           user.UserName, 
                           role.Name
                       }).ToList(); 
    }