infer se používá uvnitř conditional type pro zachycení (extrakci) typu z jiného typu do nové proměnné typu, kterou poté můžete používat. Jde o pattern-matching pro typy.
ts
<T> = T (infer U)[] ? U : ;
A = <[]>;
B = <[]>;
Čtěte to takto: "pokud se T shoduje se vzorem U[], svažte U s libovolným typem prvku a vraťte ho." infer U deklaruje placeholder, který kompilátor vyplní porovnáním.
// the resolved type of a Promise
type Awaited2<T> = T extends Promise<infer R> ? R : T;
type R = Awaited2<Promise<User>>; // User
// a function's return type (this is how ReturnType is built)
type MyReturn<T> = T extends (...args: any[]) => infer R ? R : never;
type X = MyReturn<() => number>; // number
// a function's first parameter
type FirstArg<T> = T extends (a: infer A, ...rest: any[]) => any ? A : never;
type UnwrapBoth<T> =
T extends Promise<infer U> ? UnwrapBoth<U> : // recurse to unwrap nested promises
T extends (infer E)[] ? E : T;
Můžete použít více inferů v jednom vzoru a dokonce i rekurzi.
infer je motorem vestavěných typů jako ReturnType, Parameters, Awaited a InstanceType, a stojí za knihovní magií, která odvozuje typy odpovědí z fetcherů nebo props z komponent.
Umožňuje kódu typu "otevřít" komplexní typ a vytáhnout vnitřní kusy — nejsilnější nástroj pro psaní typů, které se přizpůsobují jiným typům.