Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як працює infer в умовних типах?

infer оголошує змінну типу всередині умови умовного типу: «якщо T має таку форму, дістань звідти ось цю частину».

type ElementOf<T> = T extends readonly (infer U)[] ? U : never;

type A = ElementOf<string[]>;              // string
type B = ElementOf<readonly [1, 'a']>;     // 1 | 'a'
type C = ElementOf<number>;                // never - не масив

Так влаштовані вбудовані утиліти:

type ReturnType<T> = T extends (...args: any) => infer R ? R : any;
type Parameters<T> = T extends (...args: infer P) => any ? P : never;
type Awaited<T> = /* рекурсивно розгортає Promise і thenable */;

Практичні приклади:

// тип даних з функції, що повертає проміс
type Data<T> = T extends (...args: any[]) => Promise<infer D> ? D : never;
type UserData = Data<typeof fetchUser>;

// перший аргумент функції
type FirstArg<F> = F extends (first: infer A, ...rest: any[]) => any ? A : never;

// тип props React-компонента
type PropsOf<C> = C extends (props: infer P) => any ? P : never;

infer з шаблонними рядками - розбір рядкових типів:

type RouteParams<Path extends string> =
  Path extends `${string}:${infer Param}/${infer Rest}`
    ? Param | RouteParams<`/${Rest}`>
    : Path extends `${string}:${infer Param}`
      ? Param
      : never;

type P = RouteParams<'/teams/:teamId/users/:userId'>;   // 'teamId' | 'userId'

Так роутери (React Router, TanStack Router) типізують параметри маршрутів з рядка шляху.

infer з обмеженням (TS 4.7+) - дістати лише якщо підходить під тип:

type FirstString<T> = T extends [infer S extends string, ...unknown[]] ? S : never;

Що варто пам'ятати:

  • infer працює лише в частині extends умовного типу;
  • якщо структура не збіглася, спрацьовує гілка «інакше» - зазвичай never, і про це легко забути: тип мовчки стає never, а не помилкою;
  • кілька кандидатів для однієї змінної (infer U у кількох позиціях) дають об'єднання чи перетин залежно від позиції (коваріантна чи контраваріантна).

Перевага: не потрібно експортувати допоміжні типи з бібліотек - їх можна витягти з типів функцій і компонентів.

Докладніше в документації: Виведення в умовних типах

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання