HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptCritical

Why is the infer keyword needed in Typescript?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
typescriptwhytheinferkeywordneeded

Problem

Why did the Typescript folks create the infer keyword?
According to the documents, this is an example of how you would use it:

type ReturnType = T extends (...args: any[]) => infer R ? R : any;


I don't understand why this is needed. Why can't it just be:

type ReturnType = T extends (...args: any[]) => R ? R : any;


Why doesn't this work? Why is the infer keyword necessary ?

Solution

With infer, the compiler ensures that you have declared all type variables explicitly:

type MyType = T extends infer R ? R : never;
type T1 = MyType // T1 is { b: string; }


  • Here we declare a new type variable R in MyType, which gets inferred from T.



  • Note that infer is only used within the extends clause of a conditional type.



Without infer, the compiler does not introduce an additional type variable R2 that is to be inferred (see first case). If R2 has not been declared, it will result in a compile error:

type MyType2 = T extends R2 ? R2 : never; // error, R2 undeclared


More precisely, the compiler checks if T is assignable to R when infer is omitted:

type R = { a: number }
type MyType3 = T extends R ? R : never; // compare T with type R
type T3 = MyType3 // T3 is never


Note, that infer R shadows type references of an equally-named type declaration R:

type R = { a: number }
type MyType4 = T extends infer R ? R : never;
type T4 = MyType4 // { b: string; }


Playground

Code Snippets

type MyType<T> = T extends infer R ? R : never;
type T1 = MyType<{b: string}> // T1 is { b: string; }
type MyType2<T> = T extends R2 ? R2 : never; // error, R2 undeclared
type R = { a: number }
type MyType3<T> = T extends R ? R : never; // compare T with type R
type T3 = MyType3<{b: string}> // T3 is never
type R = { a: number }
type MyType4<T> = T extends infer R ? R : never;
type T4 = MyType4<{b: string}> // { b: string; }

Context

Stack Overflow Q#60067100, score: 154

Revisions (0)

No revisions yet.