admin管理员组

文章数量:1417551

There is a feature in typescript called ReturnType<TFunction> which allows you to infer the return type of a particular function, like so

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

However, I am having trouble using it with generic functions:

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

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

Using the top answer from Typescript ReturnType of generic function, I have tried this: (by the way this is not a duplicate, it is different as the solution and question do apply to this case)

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

I have also tried the following:

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

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

as well as

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

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

and

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

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

and also this

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

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

and this

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

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

as well as

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

and finally

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

But none of them yield the much wanted type of number[]

So, my question is, is there any way to create something similar to the builtin ReturnType which works for functions with generic parameters, given the types of the generic parameters? (aka a solution to the above problem)

There is a feature in typescript called ReturnType<TFunction> which allows you to infer the return type of a particular function, like so

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

However, I am having trouble using it with generic functions:

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

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

Using the top answer from Typescript ReturnType of generic function, I have tried this: (by the way this is not a duplicate, it is different as the solution and question do apply to this case)

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

I have also tried the following:

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

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

as well as

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

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

and

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

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

and also this

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

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

and this

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

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

as well as

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

and finally

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

But none of them yield the much wanted type of number[]

So, my question is, is there any way to create something similar to the builtin ReturnType which works for functions with generic parameters, given the types of the generic parameters? (aka a solution to the above problem)

Share Improve this question asked Aug 8, 2018 at 7:05 notrotanotrota 1,10912 silver badges22 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

I have the same problem as you and after countless workarounds not working, I found a somewhat "hack". However, this might not be convenient for all cases:

Similar to the answer given by Matt, the point is to have a dummy function, but without rewriting it. Instead of writing a dummy rewrite of your function, write a dummy function that returns a dummy usage of your function. Then, get the resulting type with ReturnType:

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

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

As of TS 3.7, unless I haven't done my research right, it still isn't possible to achieve the desired results without finding a workaround. Hopefully, we can get something that looks like this:

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

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

Given the type arguments to the function, not currently, if you follow the chain of links to Getting the return type of a function which uses generics. Given the argument types, you can write a non-generic dummy function that passes arguments of those types and then check its return type:

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

本文标签: javascriptTypeScriptReturnType of a generic function not workingStack Overflow