Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get the type of a function application in TypeScript?

How can I get the type of a generic function applied to a parameter in TypeScript?

For example, how could I define Apply below?

declare function f<T>(t: T): T extends number ? boolean : object;

type ResForNumArg = Apply<typeof f, number>;    // should be boolean
type ResForStringArg = Apply<typeof f, object>; // should be object

playground link

If there's no way to do this, one can hack around the problem for specific cases by making a type alias that is a type-level version of the function, like F below:

declare function f<T>(t: T): T extends number ? boolean : object;
type ApplyF<T> = T extends number ? boolean : object;

type ResForNumArg = ApplyF<number>;    // boolean
type ResForStringArg = ApplyF<object>; // object

But ApplyF can fall out of sync with f and is annoying to type. Is there a better way?

Update: this seems to be related to https://github.com/microsoft/TypeScript/issues/29043

like image 587
Max Heiber Avatar asked Nov 25 '25 21:11

Max Heiber


1 Answers

As you correctly have found it is not possible to use function declaration as generic type, its not possible to apply the generic without function execution. We can only apply generic during calling of the function (or will be infered from the argument):

const r1 = f<number>(1) //  boolean
const r2 = f(1) // boolean

Ok so we understand it is not possible. Now the workaround, in order to have it working without loosing connection with original declaration I propose additional generic type FType. Consider:

type FType<T> = (t: T) => T extends number ? boolean : object;
// join function declaration with FType:
declare function f<T>(...t: Parameters<FType<T>>): ReturnType<FType<T>>

type ResForNumArg =  ReturnType<FType<number>>;    // bool 
type ResForStringArg = ReturnType<FType<object>>;  // object

By using utility types Parameters and ReturnType I connected FType with function f declaration. Its verbose but we get what we want finally and FType can be applied in the standard way.

Playground link

like image 77
Maciej Sikora Avatar answered Nov 28 '25 17:11

Maciej Sikora



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!