Условные типы TypeScript
Условные типы в TypeScript предоставляют способ создания типов, зависящих от условия. Они обеспечивают большую гибкость и выразительность в определениях типов, позволяя моделировать сложные отношения типов в ясной и лаконичной манере. В этой статье рассматривается, как условные типы работают в TypeScript, и приводятся примеры, иллюстрирующие их использование.
Что такое условные типы?
Условные типы позволяют создавать типы, которые выбираются на основе условия. Они похожи на условные операторы в программировании, но работают на уровне типа. Базовый синтаксис условного типа:
type ConditionalType = T extends U ? X : Y;В этом синтаксисе:
T— проверяемый тип.Тип для сравнения — U.X— тип, возвращаемый, еслиTрасширяетU.Y— тип, возвращаемый, еслиTне расширяетU.
Базовый пример условных типов
Вот простой пример условного типа, который возвращает различные типы в зависимости от того, является ли данный тип строкой или нет:
type IsString = T extends string ? "String" : "Not a string";
type Result1 = IsString; // Result1 is "String"
type Result2 = IsString; // Result2 is "Not a string"В этом примере IsString проверяет, расширяет ли Tstring. Если да, то результатом будет "String"; в противном случае результатом будет "Not a string".
Использование условных типов с универсальными типами
Условные типы также могут использоваться с универсальными типами для создания более гибких и повторно используемых определений типов. Например, тип, который извлекает возвращаемый тип функции:
type ReturnType = T extends (...args: any[]) => infer R ? R : never;
type FunctionType = (x: number) => string;
type Result = ReturnType; // Result is stringВ этом примере ReturnType использует ключевое слово infer для вывода типа возвращаемого значения R типа функции T. Если T является типом функции, ReturnType будет типом возвращаемого значения; в противном случае по умолчанию используется never.
Условные типы с типами объединения
Условные типы также могут работать с типами union для обработки нескольких возможных типов. Например, различая разных членов union:
type ExtractString = T extends string ? T : never;
type UnionType = string | number | boolean;
type Result = ExtractString; // Result is stringВ этом примере ExtractString извлекает string из типа объединения UnionType, в результате чего получается string.
Условные типы с сопоставлением типов
Условные типы можно комбинировать с отображениями типов для создания более сложных преобразований типов. Например, отображение массива типов для применения условного типа:
type MapArray = {
[K in keyof T]: T[K] extends string ? T[K] : never;
};
type ArrayType = [string, number, boolean];
type MappedArray = MapArray; // MappedArray is [string, never, never]В этом примере MapArray сопоставляет каждый элемент массива T и применяет условный тип к каждому элементу, в результате чего получается массив, в котором сохраняются только строковые элементы.
Заключение
Условные типы в TypeScript — это мощный инструмент для создания гибких и выразительных определений типов. Используя условные типы, разработчики могут моделировать сложные отношения типов, обрабатывать различные сценарии и повышать безопасность типов в своем коде TypeScript. Понимание того, как эффективно использовать условные типы, может значительно повысить способность писать надежный и поддерживаемый код TypeScript.