← Назад к вопросам

В чем разница между Peek и Omit?

2.3 Middle🔥 172 комментариев
#TypeScript

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

В чем разница между Peek и Omit?

Контекст вопроса

Этот вопрос о TypeScript утилитах типов. Похоже, имеется в виду Pick (не Peek) и Omit - два противоположных утилиты типов для работы со свойствами объектов.

Pick - выбрать свойства

Pick создает новый тип, выбирая только указанные свойства из исходного типа:

// Исходный тип
interface User {
  id: string;
  name: string;
  email: string;
  age: number;
  phone: string;
}

// Pick - берем только id и name
type UserPreview = Pick<User, 'id' | 'name'>;

// Результат:
// {
//   id: string;
//   name: string;
// }

const preview: UserPreview = {
  id: '123',
  name: 'John'
  // email, age, phone - НЕ нужны!
};

Примеры использования Pick:

// API ответ с ограниченными данными
type UserPublicProfile = Pick<User, 'id' | 'name' | 'email'>;

// Форма регистрации (только нужные поля)
type SignUpForm = Pick<User, 'name' | 'email' | 'phone'>;

// Редактирование профиля (выбираем что можно менять)
type EditUserForm = Pick<User, 'name' | 'email' | 'phone' | 'age'>;

Omit - исключить свойства

Omit создает новый тип, исключая указанные свойства из исходного типа:

// Исходный тип (как раньше)
interface User {
  id: string;
  name: string;
  email: string;
  age: number;
  phone: string;
}

// Omit - исключаем id и age
type UserWithoutSensitive = Omit<User, 'id' | 'age'>;

// Результат:
// {
//   name: string;
//   email: string;
//   phone: string;
// }

const user: UserWithoutSensitive = {
  name: 'John',
  email: 'john@example.com',
  phone: '+1234567890'
  // id и age - исключены!
};

Примеры использования Omit:

// Создание пользователя (без id, который генерируется на сервере)
type CreateUserDto = Omit<User, 'id'>;

// Обновление (не меняем id)
type UpdateUserDto = Omit<User, 'id'>;

// Логирование (исключаем чувствительные поля)
type UserLog = Omit<User, 'phone' | 'age'>;

Прямое сравнение

Таблица сравнения:

АспектPickOmit
Что делаетВыбирает свойстваИсключает свойства
Используй когдаНужны конкретные поляНужны все, кроме некоторых
ЧитаемостьЯвно видно, что входитНужно думать об обратном
РасширяемостьПри добавлении полей нужно обновлять PickПри добавлении полей работает сразу

Практические примеры

Pick - когда знаем, что точно нужно:

interface Product {
  id: string;
  name: string;
  description: string;
  price: number;
  stock: number;
  supplier: string;
  warehouse: string;
  internalNotes: string;
}

// Публичный каталог (только базовая информация)
type ProductListItem = Pick<Product, 'id' | 'name' | 'price'>;

// Корзина (кроме описания и деталей)
type CartProduct = Pick<Product, 'id' | 'name' | 'price' | 'stock'>;

Omit - когда знаем, что нужно исключить:

interface BlogPost {
  id: string;
  title: string;
  content: string;
  author: string;
  createdAt: Date;
  updatedAt: Date;
  views: number;
  internalDraftNotes: string;
}

// При отправке на клиент (кроме черновиков)
type PublishedPost = Omit<BlogPost, 'internalDraftNotes'>;

// При создании нового поста (без id и дат)
type CreatePostDto = Omit<BlogPost, 'id' | 'createdAt' | 'updatedAt' | 'views'>;

Peek (если имеется в виду это)

Если вопрос про Peek (в контексте Zustand или Redux):

// Zustand store
const useStore = create((set, get) => ({
  counter: 0,
  increment: () => set(state => ({ counter: state.counter + 1 })),
  // get() - позволяет "посмотреть" текущее состояние без подписки
  getCounterValue: () => {
    const state = get(); // Peek - просмотр без подписки
    return state.counter;
  }
}));

Это отличается от подписки тем, что не вызывает re-render компонента.

Best Practices

Используй Pick, когда:

  • Нужны только несколько полей
  • Скорее всего добавится больше полей в тип
  • Хочешь явно показать, какие поля используются
// Лучше - явно видно, что используются
type UserSummary = Pick<User, 'id' | 'name'>;

Используй Omit, когда:

  • Нужны почти все поля, исключая 1-2
  • Уверен, что поля не изменятся
  • Нужно исключить чувствительные данные
// Лучше - видно, что исключается
type PublicUser = Omit<User, 'password' | 'internalId'>;

Расширенное использование

Комбинирование:

// Сначала Omit, потом Pick - реже, но возможно
type AdminUser = Omit<User, 'password'>;
type AdminPublicProfile = Pick<AdminUser, 'id' | 'name' | 'email'>;

// Или сразу
type AdminPublicProfile = Pick<Omit<User, 'password'>, 'id' | 'name' | 'email'>;

С Partial и Required:

// Все поля опциональны, кроме id
type UpdateDto = Partial<Omit<User, 'id'>>;

// Требуются только выбранные поля
type MinimalUser = Required<Pick<User, 'id' | 'name'>>;

Итоговое резюме

  • Pick<T, K> - берет из T только свойства K
  • Omit<T, K> - берет из T всё, кроме свойств K
  • Pick лучше когда нужно явно показать, что берется
  • Omit лучше когда нужны почти все поля
  • Оба инструмента очень полезны для DRY кода
В чем разница между Peek и Omit? | PrepBro