TypeScript: Создание собственных типов с помощью mapped types

TypeScript предоставляет мощный инструмент для работы с типами — mapped types (или «отображённые типы»). Они позволяют создавать новые типы на основе уже существующих, трансформируя их свойства. Этот инструмент незаменим, когда нужно адаптировать или модифицировать типы для конкретных задач.
Что такое mapped types?
Mapped types позволяют описать преобразование свойств одного типа в новый тип. Они работают с объектами, проходя по их ключам и применяя определённые изменения. Основой для создания mapped types является использование синтаксиса с ключевым словом in
.
type MappedType<T> = {
[K in keyof T]: T[K];
};
В этом примере создаётся новый тип, который копирует структуру и свойства исходного типа T
. Однако mapped types позволяют не только копировать, но и изменять свойства.
Практическое использование mapped types
Рассмотрим несколько примеров, где применение mapped types упрощает работу с типами.
1. Изменение доступности свойств
Часто требуется сделать все свойства объекта обязательными или, наоборот, необязательными. Mapped types позволяют это реализовать:
type MakeOptional<T> = {
[K in keyof T]?: T[K];
};
type MakeRequired<T> = {
[K in keyof T]-?: T[K];
};
interface User {
id: number;
name: string;
age?: number;
}
type OptionalUser = MakeOptional<User>;
type RequiredUser = MakeRequired<User>;
Тип OptionalUser
сделает все свойства необязательными, а RequiredUser
— обязательными.
2. Добавление модификаторов
Вы можете добавлять модификаторы, такие как readonly
, ко всем свойствам типа:
type ReadonlyType<T> = {
readonly [K in keyof T]: T[K];
};
interface User {
id: number;
name: string;
}
type ReadonlyUser = ReadonlyType<User>;
Теперь свойства типа ReadonlyUser
нельзя изменить после создания.
3. Преобразование типов свойств
С помощью mapped types можно менять типы свойств объекта. Например, сделать их строковыми:
type StringifyProperties<T> = {
[K in keyof T]: string;
};
interface User {
id: number;
name: string;
age: number;
}
type StringifiedUser = StringifyProperties<User>;
В этом примере все свойства объекта User
будут иметь тип string
.
Совмещение mapped types с другими инструментами TypeScript
Mapped types часто используются вместе с условными типами (Conditional Types
) и другими утилитами TypeScript. Например:
type NullableProperties<T> = {
[K in keyof T]: T[K] | null;
};
interface Product {
id: number;
title: string;
price: number;
}
type NullableProduct = NullableProperties<Product>;
Здесь все свойства объекта Product
могут принимать значение null
.
Mapped types находят применение во множестве сценариев разработки. Например, их активно используют при работе с REST API для автоматической типизации ответов сервера. Чтобы настроить рабочее окружение для подобных задач, ознакомьтесь с руководством по настройке VSCode для NextJS.
Заключение
Mapped types — это мощный инструмент TypeScript, который упрощает работу с типами и позволяет гибко модифицировать их свойства. Их использование сокращает объём кода и снижает вероятность ошибок, особенно в больших проектах. Освоив этот инструмент, вы сможете создавать более надёжные и масштабируемые приложения.