Pick и Omit в TypeScript: производные типы и реальные данные объекта

Pick и Omit в TypeScript: производные типы и реальные данные объекта
Содержание статьи

Pick создаёт тип из выбранных свойств, Omit исключает указанные свойства из исходного типа. Оба работают на уровне типов и не вырезают поля из объекта JavaScript. На Mentoring.digital разберём эту границу на учебной модели пользователя.

Опишите представление для списка

interface User {
  id: string;
  name: string;
  email: string;
  internalNote: string;
}

type UserCard = Pick<User, "id" | "name">;
type UserWithoutNote = Omit<User, "internalNote">;

const card: UserCard = { id: "u1", name: "Ada" };

В UserCard перечислены нужные карточке поля. Если в User добавится ещё одно свойство, оно не войдёт в этот Pick автоматически. В UserWithoutNote остаются все поля исходного типа, кроме названного исключения.

Для явно ограниченного представления удобен список разрешённых полей. Для внутренней модификации модели иногда удобнее исключение. Выбирайте по назначению, а не только по краткости записи.

Проверьте данные во время выполнения

const full: User = {
  id: "u1", name: "Ada", email: "ada@example.test",
  internalNote: "example only"
};

const typedCard: UserCard = full;
console.log(JSON.stringify(typedCard));
// В объекте остаются email и internalNote.

Присваивание переменной другого статического типа не создаёт новый объект. При сериализации исходные собственные перечисляемые поля продолжают участвовать в JSON. Ограничение автодополнения в редакторе не является удалением данных.

Чтобы сформировать объект с нужными полями, создайте его явно. Для вложенных объектов отдельно решите, какие данные должны копироваться.

function toUserCard(user: User): UserCard {
  return { id: user.id, name: user.name };
}

console.log(JSON.stringify(toUserCard(full)));
// {"id":"u1","name":"Ada"}

Не заменяйте типом проверку внешнего ответа

Pick и Omit не проверяют JSON, пришедший по сети. На границе приложения сначала нужно установить фактическую структуру и типы значений. Запись as User тоже не выполняет такую проверку.

Задание: добавьте в User поле phone. Сравните изменения обоих производных типов. Затем сравните ключи объектов full, typedCard и результата toUserCard. Почему две переменные одного типа могут содержать разный набор полей?

Связь типов с исполняемым кодом можно разобрать в обучении Frontend. Для ревью модели ответа подойдёт наставник по фронтенду.

Похожие статьи по данной теме