Поиск по сайту
Ctrl + K
Вопросы по TS

Как использовать сопоставляемые типы с условными типами в TypeScript?

TypeScript предоставляет возможность использовать сопоставляемые типы (mapped types) вместе с условными типами ( conditional types), что дает разработчикам большую гибкость в создании сложных и динамических типов. В этом ответе мы разберем, что такое сопоставляемые и условные типы, и как их можно использовать в комбинации.

Сопоставляемые типы

Сопоставляемые типы позволяют создавать новые типы на основе существующих. Например, вы можете создать новый тип, который будет отображать все свойства существующего типа, но с измененными типами.

Пример:

interface User {
    id: number;
    name: string;
    isActive: boolean;
}

// Создаем сопоставляемый тип, где все свойства User становятся необязательными
type Partial<User> = {
    [K in keyof User]?: User[K]
};

const user1: Partial<User> = {
    name: "Alice"
};

В этом примере мы создали новый тип Partial<User>, который делает все свойства интерфейса User необязательными.

Условные типы

Условные типы позволяют создавать типы на основе условия. Это похоже на операцию if-else, но в контексте определения типов.

Пример:

type IsString<T> = T extends string ? "Yes" : "No";

type Test1 = IsString<string>; // "Yes"
type Test2 = IsString<number>; // "No"

Здесь мы создали тип IsString<T>, который проверяет, является ли тип T строкой, и возвращает соответствующее значение.

Комбинирование сопоставляемых и условных типов

Теперь давайте объединим оба подхода. Мы можем создать новый тип, который будет изменять свойства исходного типа в зависимости от их типов.

Пример:

interface User {
    id: number;
    name: string;
    isActive: boolean;
}

// Создаем тип, который делает свойства User строками, если они числа
type StringifyNumbers<T> = {
    [K in keyof T]: T[K] extends number ? string : T[K]
};

type StringifiedUser = StringifyNumbers<User>;

const user2: StringifiedUser = {
    id: "1", // теперь id - строка
    name: "Bob",
    isActive: true,
};

В этом примере мы определили тип StringifyNumbers<T>, который преобразует все свойства типа T, являющиеся числами, в строки. После этого мы применили его к интерфейсу User, создав новый тип StringifiedUser.

Заключение

Сопоставляемые и условные типы в TypeScript — это мощные инструменты, которые позволяют создавать динамические и адаптивные типы. Они полезны для повышения гибкости ваших типов и улучшения поддерживаемости кода. Важно практиковаться в их использовании, чтобы лучше понять, как они работают и как могут помочь в написании более устойчивого кода.