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

Що таке умовні типи (conditional types) і як вони працюють?

Умовний тип вибирає один з двох типів залежно від перевірки - тернарний оператор на рівні типів:

T extends U ? X : Y

«Якщо T можна присвоїти U - тип X, інакше Y».

type IsString<T> = T extends string ? true : false;

type A = IsString<'hello'>;   // true
type B = IsString<42>;        // false

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

1. Тип результату залежно від аргументу:

type ApiResult<T extends 'one' | 'many'> = T extends 'one' ? User : User[];

declare function fetchUsers<T extends 'one' | 'many'>(mode: T): Promise<ApiResult<T>>;

const one = await fetchUsers('one');     // User
const many = await fetchUsers('many');   // User[]

2. Фільтрація об'єднань - так влаштовані вбудовані Exclude і Extract:

type Exclude<T, U> = T extends U ? never : T;

type Events = 'click' | 'focus' | 'keydown' | 'keyup';
type KeyEvents = Extract<Events, `key${string}`>;   // 'keydown' | 'keyup'
type Other = Exclude<Events, `key${string}`>;       // 'click' | 'focus'

never у гілці «викидає» член об'єднання.

3. NonNullable<T>, ReturnType<T>, Awaited<T> - теж умовні типи (останні два - з infer).

Особливість - розподіл по об'єднаннях: якщо перевіряється «голий» параметр типу, а передано об'єднання, умова застосовується до кожного члена окремо:

type ToArray<T> = T extends unknown ? T[] : never;
type R = ToArray<string | number>;   // string[] | number[], а не (string | number)[]

Обмеження й поради:

  • читабельність: вкладені умовні типи на кілька рівнів важко читати й підтримувати. Розбивайте на іменовані проміжні типи;
  • у реалізації функції TypeScript не може звузити умовний тип повернення за аргументом - доводиться використовувати перевантаження функції або явне приведення в реалізації;
  • глибина рекурсії обмежена: для рекурсивних умовних типів компілятор зупиняється з помилкою «Type instantiation is excessively deep».

Коли умовні типи доречні: бібліотеки й утиліти, типи API-клієнтів, похідні типи. У прикладному коді частіше вистачає об'єднань, перевантажень і узагальнень без умов.

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

Перевір себе

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

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