Комментарии (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'>;
Прямое сравнение
Таблица сравнения:
| Аспект | Pick | Omit |
|---|---|---|
| Что делает | Выбирает свойства | Исключает свойства |
| Используй когда | Нужны конкретные поля | Нужны все, кроме некоторых |
| Читаемость | Явно видно, что входит | Нужно думать об обратном |
| Расширяемость | При добавлении полей нужно обновлять 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 кода