> Что такое дженерики в TypeScript и для чего они используются (TypeScript)
Уровень: junior · Роль: backend · Категория: Технические вопросы
Компании: БФТ, ООО"Энфорс"
Стек: TypeScript
> Пример ответа
Короткий ответ
Дженерики в TypeScript - это механизм, позволяющий создавать компоненты (функции, классы, интерфейсы), которые работают с разными типами данных, сохраняя при этом строгую типизацию. Они используются для повышения переиспользуемости кода и безопасности типов, когда конкретный тип становится известен только в момент использования компонента.
Подробное объяснение
Дженерики (generics) решают проблему, когда нужно написать функцию или класс, которые могут работать с разными типами данных, но при этом не хочется терять информацию о типе. Без дженериков пришлось бы использовать any, что отключает проверку типов, или дублировать код для каждого типа.
Основная идея - параметризация типов. Вместо конкретного типа указывается параметр (обычно T), который подставляется при вызове. TypeScript автоматически выводит тип на основе переданных аргументов или позволяет указать его явно.
Дженерики работают на уровне компиляции - после транспиляции в JavaScript от них не остаётся и следа. Это чисто инструмент для разработчика и проверки типов.
На практике
В backend-разработке на TypeScript дженерики используются повсеместно:
- Типизация API-ответов:
ApiResponse<T>с полямиdata: T,error: string - Работа с базами данных:
Repository<T>для CRUD-операций - Middleware и обработчики запросов:
RequestHandler<Params, ResBody, ReqBody> - Вспомогательные утилиты:
Pick<T, K>,Partial<T>,Record<K, V>
Встроенные дженерики TypeScript (например, Promise<T>, Array<T>) - основа для работы с асинхронным кодом и коллекциями.
Пример кода
TYPESCRIPT// Простой дженерик-функцияfunction firstElement<T>(arr: T[]): T | undefined {return arr[0];}const num = firstElement([1, 2, 3]); // тип numberconst str = firstElement(['a', 'b']); // тип string// Дженерик-интерфейс для API-ответаinterface ApiResponse<T> {data: T;status: number;message: string;}// Использование с конкретным типомinterface User {id: number;name: string;}async function getUser(id: number): Promise<ApiResponse<User>> {const response = await fetch(`/api/users/${id}`);return response.json();}// Дженерик-класс для репозиторияclass Repository<T extends { id: number }> {private items: T[] = [];add(item: T): void {this.items.push(item);}getById(id: number): T | undefined {return this.items.find(item => item.id === id);}}
Как отвечать на собеседовании
Начни с простого определения: дженерики - это параметризованные типы. Приведи пример из реальной практики: типизация ответа от API или работа с коллекциями. Покажи понимание разницы между дженериками и any. Упомяни, что дженерики существуют только на этапе компиляции. Если спросят про ограничения - расскажи про extends для сужения допустимых типов.
Что проверяет интервьюер
- Понимание концепции обобщённого программирования
- Умение отличать дженерики от
anyи перегрузок функций - Знание синтаксиса:
<T>,T extends SomeType - Понимание, как дженерики повышают безопасность типов
- Практический опыт использования в реальных проектах
Типичные ошибки
- Путаница между дженериками и
any- это разные вещи,anyотключает проверку типов - Неправильное использование нескольких параметров:
function pair<T, U>(a: T, b: U) - Забывают про ограничения (
extends) когда нужно гарантировать наличие определённых свойств - Излишнее усложнение: не нужно делать дженерик, если функция работает только с одним типом
- Ошибка при работе с массивами:
T[]vsArray<T>- это одно и то же
> Похожие задачи по backend
Что такое inodes и зачем за ними наблюдать
Как планировать количество inodes при создании файловой системы
Как делать выборку связанных данных в чистом SQL
Как хранить книги и авторов в базе данных при связи многие-ко-многим
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью