Умовні типи 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 перевіряє, чи T розширює string. Якщо так, результатом є "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 буде типом повернення; інакше за замовчуванням ніколи.

Умовні типи з об’єднаними типами

Умовні типи також можуть працювати з об’єднаними типами для обробки кількох можливих типів. Наприклад, розрізнення між різними членами профспілки:

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, який зручно підтримувати.