It is used in conditional type resolution.
type MultipleInfers<T> = T extends { a: infer U, b: infer U, c: infer U } ? U : never;
type Tstring = MultipleInfers<{a: string, b: string, c: string}>;
type Tstring_or_number = MultipleInfers<{a: string, b: number, c: string}>;
const str: Tstring = "Hello world"; // type of str is just string
const str_or_number: Tstring_or_number = 2; // type of str_or_number is string | number
As you might already seen, infer
U accumulates all the types and them resolves them to a new type U.
Let’s move on and take a look at a more advanced usage of infer
where we are going to resolve a type from
a function parameter:
type Func<P, R> = (
param: P
) => R;
type FuncArg<
F extends Func<any, any>
> = F extends Func<infer P, any> ? P : never;
const myFunction = (x: number ): string => {
return "OK";
};
const paramType: FuncArg<typeof myFunction> = 2;
Breaking down the above example: ###Define a function type which will have 1 param
type Func<P, R> = (
param: P
) => R;
This will enable us to use it in the folowing way:
const func: Func<string, number> = (param: string): number => 2;
###Next steps is defining the interface for function asignment:
type FuncArgs<
F extends Func<any, any>
> = F extends Func<infer P, any> ? P : never;
Define another FuncArgs
type who will get the first param a value that extends Func<any, any>
(we are not going to restrict a type, so we are going to just use any
).
As a return we are using infer P
to destruct the first param of the function.
###Testing:
const myFunction = (x: number ): string => {
return "OK";
};
const paramType: FuncArg<typeof myFunction> = 2;
In our case we have a function with an argument of type number and as a result our paramType
will have a type number
.
You can also play with this implementation and break it so you’ll get a better understanding of how infer
works.
##Bonus
If for example we want to infer to the return type of the function we have to do this:
type FuncArgs<
F extends Func<any, any>
> = F extends Func<infer P, infer R> ? R : never;
After we’ll do this, our variables will have the type of our return functions.