简体   繁体   中英

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM