Интервью-вопрос
Что такое Pick в TypeScript
Pick выбирает часть свойств из существующего типа и создает новый тип. На практике это помогает типизировать пропсы, формы и DTO без копирования полей. При этом Pick не фильтрует реальные данные перед сетью, логами или аналитикой.
- Добавлен
- Редакция
Подготовьте короткий ответ и пару деталей на случай уточняющих вопросов.
Мини-квиз
Проверка перед разбором
Несколько быстрых вопросов перед разбором. Так проще поймать места, которые только кажутся понятными.
Вопрос 1 из 50 правильно
Разбор
Разобраться, а не зазубрить
Дальше разбираем суть, типичные уточнения и места, где легко сказать лишнее или перепутать термины.
Базовая идея
Pick это встроенный utility type в TypeScript. Он берет исходный тип и список ключей. Затем строит новый тип только с этими ключами.
type User = {
id: string;
name: string;
email: string;
isAdmin: boolean;
};
type UserPreview = Pick<User, "id" | "name">;
const preview: UserPreview = {
id: "u1",
name: "Alex",
};На интервью можно сказать так. Pick<Type, Keys> выбирает свойства из Type. Keys должен быть ключом или union ключей этого типа. Если написать ключ с ошибкой, TypeScript остановит это на проверке типов.
Что сказать на интервью
Хорошая короткая формулировка может звучать так:
Pick это утилитарный тип TypeScript для создания нового типа из части полей существующего типа. Например, если у меня есть User, но компоненту нужны только id и name, я могу написать Pick<User, "id" | "name">. Так я не дублирую типы полей и сохраняю связь с исходной моделью.
После этого добавьте практический нюанс. Pick не фильтрует реальные данные. Если в объекте есть password, token или внутренняя роль, тип Pick сам по себе не удалит их перед отправкой в API, лог или аналитику.
Как выбрать Pick, Omit или отдельный тип
Как выбрать подход
Используйте Pick, чтобы не дублировать имена и типы полей.Чаще удобнее Omit. Иначе список ключей в Pick быстро разрастется.Подумайте об отдельном типе и явном маппере. Pick может слишком сильно связать контракт с доменной моделью, особенно для ответа API, аналитики или данных в localStorage.Примените Pick к вложенному типу отдельно. Обычный Pick не работает глубоко.Выбор зависит не от вкуса, а от границы в коде. Если вы делаете пропсы для маленькой карточки пользователя, Pick часто уместен. Если описываете публичный контракт API, payload формы, событие аналитики или данные для localStorage, отдельный тип и явный маппер могут быть безопаснее.
Сильный ответ показывает этот trade-off. Pick уменьшает дублирование, но усиливает связность. Иногда это плюс, иногда риск.
Практический пример в React
Типичный frontend-сценарий такой. Есть большой тип пользователя, но карточке в списке нужны только несколько полей.
type User = {
id: string;
name: string;
avatarUrl?: string;
email: string;
role: "user" | "admin";
};
type UserCardProps = Pick<User, "id" | "name" | "avatarUrl">;
function UserCard({ id, name, avatarUrl }: UserCardProps) {
return (
<article>
{avatarUrl ? <img src={avatarUrl} alt={`Avatar of ${name}`} /> : null}
<h3>{name}</h3>
<a href={`/users/${id}`}>Open profile</a>
</article>
);
}Практический плюс такой. Если тип avatarUrl в User изменится, пропсы карточки обновятся вместе с ним. Практический риск тоже есть. Компонент становится связан с User. Если карточка должна показывать не только пользователей, но и авторов из другого API, лучше описать отдельный тип пропсов. Еще один frontend-нюанс. Pick не проверяет, что URL картинки безопасен или что текст подходит для доступности. Это решают в коде компонента и при валидации данных.
Ограничения, которые лучше назвать
Первое ограничение. Pick работает только с типами. Ниже плохой пример, если вы думаете, что так очищаете данные:
type PublicUser = Pick<User, "id" | "name">;
const publicUser = user as PublicUser;
sendAnalytics(publicUser);Это плохой пример, потому что as PublicUser не удаляет лишние поля из объекта. Если user содержал email, token, password или role, они могут остаться в runtime-объекте и попасть в аналитику или сетевой payload. Безопаснее собрать новый объект явно.
const publicUser: PublicUser = {
id: user.id,
name: user.name,
};Второе ограничение. Pick не делает глубокий выбор.
type User = {
id: string;
profile: {
city: string;
phone: string;
};
};
type UserProfile = Pick<User, "profile">;
type UserCity = Pick<User["profile"], "city">;UserProfile содержит весь объект profile, включая phone. Если потом передать такой объект в дочерний компонент, лог или запрос, лишнее поле останется в данных. Если вам нужен только city, применяйте Pick к User["profile"] и собирайте объект с нужными полями явно.
Практический вывод
На интервью не нужно перечислять все utility types. Лучше показать, что вы понимаете назначение Pick, границы его работы и практические последствия.
Сильный ответ состоит из трех частей. Что делает Pick, где вы применяли бы его во frontend-коде, и чего он не делает. Например, он помогает типизировать пропсы, формы и DTO. Но он не фильтрует реальные данные перед сетью, логами или аналитикой и не выбирает вложенные поля сам.
Частые ошибки
Где обычно ошибаются
Проверьте формулировки, которые звучат уверенно, но на интервью быстро выдают пробелы.
- 1
Думать, что Pick меняет данные в runtime
Pickработает только на уровне типов. Он не удаляет поля из объекта в JavaScript и не очищает данные перед отправкой на сервер, в аналитику или вlocalStorage. Так вы можете случайно передатьemail,tokenили флаг роли. Если нужно убрать лишние поля на самом деле, соберите новый объект явно. - 2
Путать Pick и Omit
Pickвыбирает перечисленные поля, аOmitисключает их. Если перепутать эти типы в пропсах или DTO, можно случайно разрешить лишние поля или потерять обязательные данные для UI. - 3
Ждать глубокий выбор полей
Pick<User, "profile">выберет все полеprofile, а не отдельные свойства внутри него. Для вложенного выбора используйтеPick<User["profile"], "city">или отдельный тип. - 4
Тянуть доменную модель в каждый компонент
Pick<User, "id" | "name">удобен для простого компонента, но не всегда подходит для публичного API или сложной формы. Если контракт должен жить отдельно от моделиUser, лучше назвать его явно и не прятать важную границу за Pick.
Follow-up
Что могут спросить дальше
Короткие ответы на вопросы, где важно показать понимание Pick, keyof и границ TypeScript.
Живые ответы
Видео с похожим вопросом
Если найдем публичные интервью с таким вопросом, добавим их сюда. Их удобно смотреть после теории, чтобы свериться с живыми ответами.
Пока видео нет. Когда появятся подходящие публичные интервью, добавим их в этот блок, чтобы можно было сравнить разбор с тем, как отвечают реальные кандидаты.
Что такое Mapped Types 😎
Mapped Types создают новый тип по ключам существующего типа и меняют свойства без дублирования. Разбираем синтаксис, связь с Utility Types, key remapping и риски для DTO и UI-состояния.
Что будет, если создать два интерфейса с одинаковым именем в одном файле 😎
TypeScript объединит одноименные интерфейсы через declaration merging, а не перезапишет первый вторым. Разбираем, где это полезно, где приводит к ошибке компиляции и как безопасно говорить об этом на интервью.