Conditional Types (условные типы) — это продвинутая возможность TypeScript, позволяющая создавать типы, которые выбирают одну из двух возможных структур на основе условия. Синтаксис похож на тернарный оператор: T extends U ? X : Y. Если тип T можно присвоить типу U, то результатом будет тип X, иначе — Y.
Условные типы открывают дорогу для создания невероятно гибких и выразительных типов, которые адаптируются под входные данные. Они часто используются вместе с generic-параметрами в типах-утилитах (как встроенных, так и пользовательских). Например, они могут определить, является ли переданный тип массивом, чтобы вернуть тип его элементов.
Изучение conditional types кажется сложным, но наш практический тренажер разбивает его на понятные шаги. Вы будете решать задания, где нужно предсказать результат условного типа для конкретного входного типа или собрать условный тип из частей. Такие тренировки без сухой теории и с визуализацией кода помогают глубоко понять механику работы. Этот онлайн-урок TypeScript бесплатно даст вам инструмент для профессиональной разработки сложных типовых систем.
- Модуль 1: Введение в TypeScript
- Модуль 2: Примитивные типы
- Модуль 3: Специальные типы
- Модуль 4: Массивы
- Модуль 5: Кортежи (Tuples)
- Модуль 6: Объекты
- Модуль 7: Функции
- Модуль 8: Union типы
- Модуль 9: Литеральные типы
- Модуль 10: Type Aliases
- Модуль 11: Интерфейсы
- Модуль 12: Type Guards и Narrowing
- Модуль 13: Enums
- Модуль 14: Классы
- Модуль 15: Generics — основы
- Модуль 16: Generics — ограничения
- Модуль 17: Utility Types — базовые
- Модуль 18: Utility Types — работа с Union
- Модуль 19: Utility Types — функции
- Модуль 20: Type Assertions
- Модуль 21: Keyof и Typeof операторы
- Модуль 22: Mapped Types
- Модуль 23: Conditional Types
- Основы Conditional Types.
- Distributive Conditional Types.
- Ключевое слово infer.
- Модуль 24: Discriminated Unions
- Модуль 25: Модули и типы
- Модуль 26: Declaration Files
- Модуль 27: Типизация асинхронного кода
- Модуль 28: Практические паттерны
1. Дополни условие типа
В этом задании вам предстоит дополнить условие в условном типе TypeScript. Условные типы (Conditional Types) позволяют выбирать один из двух типов на основе условия, заданного через `extends`. Вам дан тип `IsString
// Этот тип проверяет, является ли T строковым типом
type IsString<T> = T extends input1S ? true : false;2. Построй условный тип
Перед вами перемешанные части условного типа TypeScript. Условный тип позволяет выбирать один из двух типов на основе условия, которое проверяет, удовлетворяет ли один тип другому. Соберите из этих частей корректный синтаксис условного типа, который проверяет, является ли тип T строкой (string). Если да, то результатом будет сам тип T, иначе — тип never. Расставьте строки в правильном порядке сверху вниз, чтобы получился валидный TypeScript-код.
extends string? TT: never3. Выбери результирующий тип
В этом задании представлены три условных типа TypeScript. Для каждого из них указан конкретный тип-аргумент. Определите, какой тип будет получен в результате вычисления условного типа, и выберите его из выпадающего списка. Обратите внимание на то, как условные типы распределяют типы по веткам в зависимости от условия.
type Type1<T> = T extends string ? string : number;
type Test1 = Type1<"abc">; // Результат: input1S
type Type2<T> = T extends number ? number : never;
type Test2 = Type2<boolean>; // Результат: input2S
type Type3<T> = T extends any[] ? T[number] : T;
type Test3 = Type3<string[]>; // Результат: input3S4. Сопоставь условие и результат
В левой колонке приведены условия для условных типов (Conditional Types) в TypeScript. В правой колонке — возможные результирующие типы в ветке истины (true branch). Сопоставьте каждое условие слева с соответствующим результатом справа. Обратите внимание, что в правой колонке нет лишних вариантов, но порядок элементов перемешан. Всего нужно сопоставить 5 пар.
T extends string ? T : neverT extends (infer U)[] ? U : neverT extends Promise<infer R> ? R : neverT extends { length: number } ? number : neverT extends null | undefined ? never : TRnumberTUT5. Какой тип получит переменная?
Проанализируйте объявление условного типа Check и его использование для определения типов переменных. Исходя из логики условного типа, определите, какой конкретный тип будет присвоен переменной d в данном фрагменте кода TypeScript.
type Check<T> = T extends string | number ? T : boolean;
let a: Check<string>; // тип: string
let b: Check<number>; // тип: number
let c: Check<boolean>; // тип: boolean
let d: Check<string | number>; // тип: ?6. Найди все условные типы
Внимательно изучите приведённый ниже код на TypeScript. В нём содержатся объявления типов (ключевое слово `type`). Ваша задача — найти и отметить только те объявления, которые представляют собой условные типы. Условный тип в TypeScript использует синтаксис с вопросительным знаком и двоеточием (`? :`). Не отмечайте объявления, которые не содержат условных выражений.
{{type IsString<T> = T extends string ? true : false;~|~t1}}
{{type MyNumber = number;~|~t2}}
{{type Status = 'active' | 'inactive';~|~t3}}
{{type GetReturnType<T> = T extends (...args: any[]) => infer R ? R : never;~|~t4}}
{{type User = { name: string; age: number };~|~t5}}
{{type IsArray<T> = T extends any[] ? true : false;~|~t6}}
{{type Flatten<T> = T extends (infer U)[] ? U : T;~|~t7}}7. Вычисли условный тип
Проанализируйте TypeScript-код сверху и восстановите последовательность логических шагов вычисления условного типа. Шаги снизу перемешаны — расставьте их в правильном порядке, чтобы отразить, как TypeScript вычисляет итоговый тип для заданного входного типа.
type Unwrap<T> = T extends Promise<infer U>
? (U extends Array<infer V> ? V[] : U)
: T;
// Вычисление для конкретного типа
type Result = Unwrap<Promise<string[]>>;U extends Array<infer V> — истинаV = string с помощью inferU = string[] с помощью inferT extends Promise<infer U> — истинаstring[] (массив строк)T = Promise<string[]>