Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
TypeScript Omit: исключение свойств из типов
Что такое Omit?
Omit — это встроенный утилитарный тип TypeScript, который создаёт новый тип на основе существующего, но исключает указанные свойства. Это противоположность Pick, который наоборот берёт только нужные свойства.
Синтаксис:
type NewType = Omit<OriginalType, "propertyName1" | "propertyName2">;
Практические примеры
Пример 1: Исключение чувствительных данных
interface User {
id: string;
name: string;
email: string;
password: string;
createdAt: Date;
}
// Тип для отправки клиенту (без пароля)
type PublicUser = Omit<User, "password">;
// PublicUser имеет структуру:
// { id: string; name: string; email: string; createdAt: Date; }
const user: PublicUser = {
id: "123",
name: "John",
email: "john@example.com",
createdAt: new Date(),
// password: "..." // ❌ Error: не может быть использовано
};
Пример 2: Исключение нескольких полей
interface BlogPost {
id: string;
title: string;
content: string;
author: string;
createdAt: Date;
updatedAt: Date;
views: number;
comments: Comment[];
}
// Тип для отправки на API (без служебных полей)
type CreatePostRequest = Omit<BlogPost, "id" | "createdAt" | "updatedAt" | "views" | "comments">;
// CreatePostRequest = { title: string; content: string; author: string; }
async function createPost(payload: CreatePostRequest) {
const response = await fetch("/api/posts", {
method: "POST",
body: JSON.stringify(payload),
});
return response.json();
}
Пример 3: Наследование с исключением
interface BaseComponent {
id: string;
className?: string;
onClick?: () => void;
disabled?: boolean;
data?: Record<string, any>;
}
// Компонент Button без некоторых полей
interface ButtonProps extends Omit<BaseComponent, "data"> {
label: string;
variant?: "primary" | "secondary";
}
const Button: React.FC<ButtonProps> = ({
id,
className,
onClick,
disabled,
label,
variant = "primary",
}) => {
return (
<button
id={id}
className={className}
onClick={onClick}
disabled={disabled}
>
{label}
</button>
);
};
Пример 4: Обновление в базе данных
interface Product {
id: string;
name: string;
description: string;
price: number;
stock: number;
createdAt: Date;
updatedAt: Date;
createdBy: string;
}
// Для обновления продукта: исключаем id и служебные поля
type UpdateProductRequest = Omit<Product, "id" | "createdAt" | "updatedAt" | "createdBy">;
async function updateProduct(id: string, payload: UpdateProductRequest) {
const response = await fetch(`/api/products/${id}`, {
method: "PATCH",
body: JSON.stringify(payload),
});
return response.json();
}
// Использование
updateProduct("123", {
name: "New Name",
description: "New Description",
price: 99.99,
stock: 50,
// id, createdAt, updatedAt, createdBy — не требуются
});
Пример 5: React компонент с Omit
interface HTMLInputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}
interface CustomInputProps extends Omit<HTMLInputProps, "onChange" | "onBlur"> {
onChange?: (value: string) => void;
onBlur?: (value: string) => void;
label?: string;
error?: string;
}
const CustomInput: React.FC<CustomInputProps> = ({
label,
error,
onChange,
onBlur,
...rest
}) => {
return (
<div>
{label && <label>{label}</label>}
<input
{...rest}
onChange={(e) => onChange?.(e.target.value)}
onBlur={(e) => onBlur?.(e.target.value)}
/>
{error && <span className="error">{error}</span>}
</div>
);
};
Omit vs Pick
interface User {
id: string;
name: string;
email: string;
age: number;
}
// Pick: берёт только указанные свойства
type UserPreview = Pick<User, "name" | "email">;
// { name: string; email: string; }
// Omit: исключает указанные свойства
type UserWithoutEmail = Omit<User, "email">;
// { id: string; name: string; age: number; }
Когда использовать Omit?
✅ Используй Omit когда:
- Нужно исключить чувствительные данные (пароли, токены)
- Разные версии одного типа для разных операций (create, update, view)
- Наследуешь типы и хочешь переопределить некоторые поля
- Работаешь с API и нужны разные типы запросов/ответов
❌ Не используй Omit если:
- Исключаемых свойств больше половины (используй
Pick) - Часто меняется список исключаемых свойств (сделай явный интерфейс)
- Нужна полная типизация (явный интерфейс лучше читается)
Продвинутые примеры
Исключение множественных типов:
interface Config {
apiUrl: string;
timeout: number;
retries: number;
debug: boolean;
logger: Logger;
cache: CacheManager;
}
// Для клиента отправляем только строковые и числовые конфиги
type ClientConfig = Omit<Config, "logger" | "cache">;
Комбинирование с другими утилитами:
interface Form {
id: string;
name: string;
fields: Field[];
createdAt: Date;
updatedAt: Date;
}
// Исключаем временные метки и делаем всё опциональным
type PartialFormUpdate = Partial<Omit<Form, "createdAt" | "updatedAt">>;
const formUpdate: PartialFormUpdate = {
name: "New Form",
// остальное опционально
};
Заключение
Omit — это мощный утилитарный тип, который помогает создавать чистые и безопасные типы данных. Используй его для исключения чувствительных данных, служебных полей и для создания разных версий одного типа для разных операций. Это делает код более типобезопасным и читаемым.