Фреймворк Fresh для JavaScript и TypeScript построен на принципах минимализма и высокой производительности. Одним из ключевых аспектов при работе с TypeScript в Fresh является использование utility types — встроенных типов, которые позволяют гибко манипулировать типами данных и обеспечивать строгую типизацию без избыточного кода.
Utility types особенно полезны для работы с компонентами, маршрутами и данными API, где структуры данных могут быть сложными и динамическими.
Partial<T>Тип Partial<T> делает все свойства интерфейса или
типа необязательными. Это удобно при частичном
обновлении состояния компонентов или при работе с объектами, полученными
из внешнего API.
Пример:
interface User {
id: number;
name: string;
email: string;
}
const updateUser: Partial<User> = {
email: "new@example.com"
};
В данном примере объект updateUser может содержать
любую комбинацию свойств, включая их отсутствие.
Использование Partial в Fresh:
signals.Required<T>Противоположность Partial. Тип
Required<T> делает все свойства типа
обязательными. Особенно полезен при строгой валидации
данных, когда необходимо гарантировать наличие всех полей.
interface Config {
host?: string;
port?: number;
}
const fullConfig: Required<Config> = {
host: "localhost",
port: 8080
};
В контексте Fresh это помогает гарантировать корректную инициализацию
конфигурации приложения, например, при работе с
Deno.env.
Readonly<T>Тип Readonly<T> делает все свойства объекта
только для чтения. Применение этого типа позволяет
предотвратить случайное изменение данных, что важно при работе с
immutable state и серверным рендерингом.
interface Post {
id: number;
title: string;
}
const post: Readonly<Post> = { id: 1, title: "Fresh Guide" };
// post.title = "New Title"; // Ошибка
В Fresh Readonly используется для безопасной передачи
пропсов между компонентами без риска их изменения.
Record<K, T>Record<K, T> создаёт объект с ключами типа
K и значениями типа T. Этот utility type
незаменим для маппинга данных или создания словарей.
Пример:
type PageRoutes = "home" | "about" | "contact";
const routes: Record<PageRoutes, string> = {
home: "/",
about: "/about",
contact: "/contact"
};
В Fresh это особенно полезно при организации маршрутов и статической генерации страниц.
Pick<T, K> и
Omit<T, K>Эти типы позволяют выбирать или исключать свойства из интерфейсов.
Pick<T, K> — выбирает только указанные
свойства.Omit<T, K> — исключает указанные свойства.Пример с Pick:
interface User {
id: number;
name: string;
email: string;
}
type UserPreview = Pick<User, "id" | "name">;
const preview: UserPreview = { id: 1, name: "Alice" };
Пример с Omit:
type UserWithoutEmail = Omit<User, "email">;
const user: UserWithoutEmail = { id: 1, name: "Bob" };
Использование в Fresh:
Exclude<T, U> и
Extract<T, U>Эти utility types работают с сочетаниями типов.
Exclude<T, U> исключает типы, содержащиеся в
U.Extract<T, U> оставляет только те типы, которые
присутствуют в U.Пример:
type Status = "active" | "inactive" | "pending";
type ActiveStatus = Exclude<Status, "inactive">; // "active" | "pending"
type PendingStatus = Extract<Status, "pending" | "inactive">; // "inactive" | "pending"
В Fresh полезно для строгой типизации состояний компонентов или событий.
NonNullable<T>Удаляет null и undefined из типа.
type OptionalString = string | null | undefined;
type StringOnly = NonNullable<OptionalString>; // string
Используется при обработке данных из API, чтобы гарантировать, что значения всегда присутствуют.
ReturnType<T> и
Parameters<T>ReturnType<T> возвращает тип результата
функции.Parameters<T> возвращает кортеж типов аргументов
функции.Пример:
function fetchUser(id: number) {
return { id, name: "Alice" };
}
type UserType = ReturnType<typeof fetchUser>; // { id: number; name: string; }
type ArgsType = Parameters<typeof fetchUser>; // [number]
В Fresh помогает при строгой типизации хендлеров маршрутов и серверных функций.
Utility types можно комбинировать для достижения сложной типовой логики. Например:
interface Product {
id: number;
name: string;
price?: number;
}
type ReadonlyPartialProduct = Readonly<Partial<Product>>;
const product: ReadonlyPartialProduct = { name: "Laptop" };
// product.name = "Phone"; // Ошибка
Такое сочетание делает объект одновременно необязательным и неизменяемым, что полезно для безопасной работы с пропсами и API ответами.
Utility types в Fresh являются основой безопасной и гибкой работы с
данными. Их применение минимизирует количество ошибок на этапе
компиляции, повышает читаемость кода и упрощает поддержку проекта.
Комплексное владение Partial, Required,
Readonly, Record, Pick,
Omit, Exclude, Extract,
NonNullable, ReturnType и
Parameters позволяет создавать приложения с чистой
архитектурой и строгой типизацией.