Ответ
Conditional Types в TypeScript позволяют создавать типы, которые зависят от условий. Они используют синтаксис 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
Используются часто с infer для извлечения типов:
type UnpackPromise<T> = T extends Promise<infer U> ? U : T;
type C = UnpackPromise<Promise<number>>; // number
type D = UnpackPromise<string>; // string
Особенности:
- Работают на уровне типов, не влияют на runtime
- Полезны для сложных generic-типов
- Могут быть рекурсивными
Ответ 18+ 🔞
Ну ты смотри, какие штуки TypeScript выкатывает! 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, это ж число, ты че, слепой?
Но это цветочки. Ягодки начинаются, когда к делу подключается infer. Это такая хитрая жопа, которая вытаскивает тип из самого нутра другой конструкции, как изюм из булки.
type UnpackPromise<T> = T extends Promise<infer U> ? U : T;
type C = UnpackPromise<Promise<number>>; // number, вытащил на свет божий, молодец
type D = UnpackPromise<string>; // string, а тут и вытаскивать нехуй, так и оставил
И главное, запомни, чувак: вся эта магия творится только в мире типов. В рантайме от этого ни хуя не остаётся, всё выметается. Но без них, блядь, когда дженерики становятся сложнее грёбаного кроссворда, жить невозможно. А ещё их можно заставить повторяться самих себя, как попугая, — рекурсивными сделать. В общем, мощная хуйня, хоть и выглядит как обычный тернарник.