infer jest używane wewnątrz conditional type do przechwycenia (wyodrębnienia) typu z wnętrza innego typu do nowej zmiennej typu, którą następnie można użyć. Jest to dopasowanie wzorca dla typów.
<T> = T (infer U)[] ? U : ;
A = <[]>;
B = <[]>;
infer jest używane wewnątrz conditional type do przechwycenia (wyodrębnienia) typu z wnętrza innego typu do nowej zmiennej typu, którą następnie można użyć. Jest to dopasowanie wzorca dla typów.
<T> = T (infer U)[] ? U : ;
A = <[]>;
B = <[]>;
Czytaj to jako: "jeśli T pasuje do wzorca U[], powiąż U z rzeczywistym typem elementu i zwróć go." infer U deklaruje symbol zastępczy, który kompilator wypełnia przez dopasowanie wzorca.
infer jest silnikiem stojącym za wbudowanymi typami takimi jak ReturnType, Parameters, Awaited i InstanceType, oraz za magią biblioteczną, która pochodzi z typów odpowiedzi od pobieraczy lub właściwości z komponentów.
Pozwala kodzie typu "otworzyć" złożony typ i wyodrębniać wewnętrzne części — najmocniejsze narzędzie do pisania typów, które dostosowują się do innych typów.
// 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;
Możesz użyć kilku inferów w jednym wzorcu, a nawet rekurencji.