Используешь ли условные типы (conditional types) в TypeScript
Что проверяют
Умеете ли вы пользоваться системой типов как инструментом, а не только подписывать props. Вопрос «используешь ли» подразумевает пример из практики, а следом обычно спрашивают про infer и дистрибутивность на объединениях.
Как отвечать
Синтаксис T extends U ? X : Y: если T совместим с U, получаем X, иначе Y. Дальше важно показать, что вы понимаете механику.
- встроенные утилиты:
Exclude,Extract,NonNullable,ReturnType,Parameters,Awaitedсами построены на условных типах. Пользуетесь ими, значит, уже пользуетесь условными типами; infer: вытаскивает часть типа.type ElementOf<T> = T extends (infer E)[] ? E : neverвозвращает тип элемента массива;- дистрибутивность: если
Tголый параметр и в него пришло объединение, условие применяется к каждому члену отдельно.Exclude<'a' | 'b', 'a'>даёт'b'именно поэтому. Отключается обёрткой в кортеж:[T] extends [U]; - рекурсия: условный тип может ссылаться на себя, так пишут
DeepPartialили разбор строки через шаблонные литеральные типы.
Примеры из фронтенда, которые хорошо звучат: извлечение параметров из маршрута '/users/:id' в объект { id: string }, тип ответа API в зависимости от эндпоинта, пропсы полиморфного компонента, где набор атрибутов зависит от as.
Уместно сказать и о цене: сложные типы замедляют проверку в редакторе, а ошибка на пять экранов не помогает коллегам. Условным типам место в утилитах и типах библиотек, в прикладном коде обычно хватает дженериков и перегрузок.
Где спотыкаются
Не знают про дистрибутивность и удивляются результату. Для type IsString<T> = T extends string ? true : false вызов IsString<string | number> даёт boolean, то есть true | false, а IsString<never> превращается в never.
Ждут, что условный тип сузит значение внутри реализации функции. Если функция объявляет возвращаемый тип T extends string ? A : B, TypeScript в теле обычно не может проверить ветку, и приходится писать приведение типа или перегрузки.
Пишут слишком глубокую рекурсию и получают ошибку Type instantiation is excessively deep and possibly infinite, а на вопрос о причине отвечают «TypeScript глючит».