Что такое Pick в TypeScript и как его использовать?
Что проверяют
Владеете ли вы утилитными типами как инструментом, а не набором заклинаний: понимаете ли, что Pick это обычный отображённый тип, и умеете ли выводить типы из одного источника вместо ручного дублирования интерфейсов во всех слоях приложения.
Как отвечать
Pick строит новый тип из подмножества свойств существующего. Определение в стандартной библиотеке короткое, и его полезно назвать:
type Pick<T, K extends keyof T> = { [P in K]: T[P] };
interface User { id: number; name: string; email?: string }
type UserPreview = Pick<User, "id" | "name">;Ключи ограничены keyof T, поэтому опечатка в имени свойства даёт ошибку компиляции, а не молчаливо пустой тип. Модификаторы сохраняются: необязательность и readonly переезжают в новый тип вместе со свойством.
Где применяют: пропсы компонента, которому нужна часть модели; тип аргумента для создания сущности, где сервер сам проставит идентификатор и даты; публичный тип ответа, собранный из внутренней сущности. Парный к Pick тип это Omit, он описывает дополнение по тому же набору ключей.
type CardProps = Pick<User, "id" | "name"> & { onSelect(id: number): void };Стоит упомянуть, что Pick работает по верхнему уровню: вложенные объекты берутся целиком, для отбора внутри них пишут собственный рекурсивный тип.
Где спотыкаются
Применяют Pick к объединению типов и удивляются, что размеченное объединение схлопнулось в один объект. Сам по себе Pick по членам объединения не распределяется, для этого нужна обёртка через условный тип с T extends unknown.
Считают Omit таким же строгим. В его сигнатуре ключи не ограничены keyof T, поэтому опечатка или переименованное поле проходят молча, и тип остаётся шире задуманного, а ошибка вылезает уже в рантайме.
Тянут Pick туда, где форма данных совпала с моделью случайно. Если у формы своя валидация и свой набор полей, честнее описать отдельный тип: связка через Pick начнёт ломать экран при каждой правке сущности на бекенде.