> Используешь ли условные типы (conditional types) в TypeScript (TypeScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Арго
Стек: TypeScript
> Пример ответа
Короткий ответ
Да, регулярно использую условные типы для создания гибких и типобезопасных абстракций. Они позволяют выводить типы на основе условий, что особенно полезно при работе с перегрузками функций, discriminated unions и трансформациями типов. Основные сценарии: извлечение типов из сложных структур, создание type-safe API для библиотек и реализация паттернов вроде infer для вывода внутренних типов.
Подробное объяснение
Условные типы в TypeScript - это мощный инструмент для построения типов, зависящих от других типов. Они работают по принципу тернарного оператора: T extends U ? X : Y. Ключевая особенность - дистрибутивность: если T - union, условие применяется к каждому элементу union отдельно.
На практике я использую их для:
- Извлечения типов из сложных структур через
infer(например,ReturnType<T>,Parameters<T>) - Создания discriminated type guards без runtime-кода
- Построения type-safe middleware и HOC в React
- Реализации conditional return types для перегруженных функций
- Трансформации типов (например,
NonNullable<T>,Exclude<T, U>)
Важно понимать trade-off: чрезмерное использование условных типов может усложнить читаемость и замедлить компиляцию. Оптимальный подход - применять их для публичных API библиотек и сложных generic-абстракций, избегая в простых утилитах.
На практике
В реальных проектах условные типы незаменимы при работе с:
- API-клиентами: автоматическое определение типов ответов на основе параметров запроса
- State management: типизация редьюсеров с discriminated actions
- React-компонентами: создание пропсов, зависящих от других пропсов (conditional props)
- Utility types: кастомные утилиты вроде
DeepPartial<T>,PickByValue<T, V>
Типичный сценарий - создание type-safe функции, которая принимает разные типы и возвращает соответствующий результат без использования any. Например, функция для работы с localStorage, где тип возвращаемого значения зависит от переданного default-значения.
Пример кода
TYPESCRIPT// Извлечение типа из Promisetype Unwrap<T> = T extends Promise<infer U> ? U : T;type Result = Unwrap<Promise<string>>; // string// Conditional return type для функцииfunction getConfig<T extends boolean>(withDefaults: T): T extends true ? { theme: string; lang: string } : { theme?: string; lang?: string } {return withDefaults? { theme: 'light', lang: 'en' } as any: {} as any;}// Discriminated union с условными типамиtype Event =| { type: 'click'; x: number; y: number }| { type: 'keypress'; key: string };type EventHandler<T extends Event['type']> =T extends 'click'? (event: { x: number; y: number }) => void: T extends 'keypress'? (event: { key: string }) => void: never;// Utility type с infertype DeepReadonly<T> = {readonly [K in keyof T]: T[K] extends object? DeepReadonly<T[K]>: T[K];};
Как отвечать на собеседовании
Начни с конкретного примера использования в реальном проекте, затем объясни механизм работы. Покажи понимание дистрибутивности и infer. Упомяни, когда условные типы избыточны (например, для простых маппингов лучше использовать mapped types). Хорошо продемонстрировать знание встроенных условных типов (ReturnType, InstanceType) и умение создавать кастомные.
Что проверяет интервьюер
- Понимание системы типов TypeScript на продвинутом уровне
- Умение проектировать гибкие и безопасные API
- Знание trade-off между сложностью типов и читаемостью кода
- Способность применять абстрактные концепции к реальным задачам
- Понимание внутренних механизмов TypeScript (дистрибутивность, infer, conditional chains)
Типичные ошибки
- Забывают про дистрибутивность условных типов для union-типов
- Используют условные типы там, где достаточно простого generic или overload
- Создают бесконечную рекурсию через условные типы без базового случая
- Путают
extendsв условных типах с наследованием классов - Чрезмерно усложняют типы, делая код нечитаемым для других разработчиков
- Не учитывают производительность: сложные цепочки условных типов замедляют компиляцию
> Похожие задачи по frontend
Для чего используется infer в TypeScript
Использовал ли ты mapped types в TypeScript
Что происходит при объединении полей с конкретными значениями в TypeScript?
Что такое дженерики в TypeScript и для чего они используются
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью