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

Понимание типов союзов

Типы объединения в TypeScript позволяют определить тип, представляющий значение, принадлежащее к одному из нескольких возможных типов. Это полезно, когда вы хотите смоделировать переменную или параметр функции, которые могут принимать различные формы. Вот пример типа объединения:

type StringOrNumber = string | number;
let value: StringOrNumber;

Введение в объединения с тегами

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

Теговое объединение — это тип объединения, в котором каждый тип члена имеет уникальное свойство «тег» или «дискриминатор», которое позволяет TypeScript определять, к какому типу члена принадлежит значение. Этот тег обычно является строковым литералом или числовым литералом.

Чтобы определить объединение с тегами, необходимо создать типы элементов с уникальным свойством тега, а затем определить объединяющий их тип объединения. Вот пример:

interface Circle {
  kind: "circle";
  radius: number;
}

interface Square {
  kind: "square";
  sideLength: number;
}

type Shape = Circle | Square;

В этом примере мы определяем два интерфейса, Circle и Square, с уникальным свойством kind, которое служит тегом. Затем мы создаем тип объединения Shape, который объединяет эти интерфейсы.

Защиты типов и размеченные объединения

TypeScript использует свойство уникального тега для автоматического создания защиты типов, что позволяет различать типы элементов объединения с тегами. Вот пример:

function getArea(shape: Shape): number {
  switch (shape.kind) {
    case 'circle':
      return Math.PI * shape.radius ** 2;
    case 'square':
      return shape.sideLength ** 2;
    default:
      // Ensures exhaustive checking of Shape types
      const _exhaustiveCheck: never = shape;
      return _exhaustiveCheck;
  }
}

В этом примере TypeScript использует свойство kind, чтобы сузить тип shape в каждом блоке case, что позволяет безопасно получить доступ к определенным свойствам каждого типа члена.

Расширенное использование объединений с тегами

Объединения с тегами можно использовать в более сложных сценариях для моделирования сложных структур данных и дальнейшего повышения безопасности типов.

Рекурсивные объединения с тегами

Объединения с тегами можно использовать для моделирования рекурсивных структур данных, таких как деревья:

interface TreeNode {
  value: number;
}

interface BranchNode extends TreeNode {
  kind: 'branch';
  left: Tree;
  right: Tree;
}

interface LeafNode extends TreeNode {
  kind: 'leaf';
}

type Tree = BranchNode | LeafNode;

В этом примере мы определяем структуру данных двоичного дерева, используя помеченные объединения. Тип Tree используется рекурсивно в интерфейсе BranchNode для представления левого и правого поддеревьев.

Типы служебных программ и сопоставленные типы

Объединения с тегами можно использовать в сочетании с служебными типами TypeScript и сопоставленными типами для создания более гибких определений типов:

type NullableShape = {
  [K in keyof Shape]: Shape[K] | null;
};

type ReadonlyShape = Readonly<Shape>;

В этих примерах мы используем сопоставленный тип NullableShape для создания версии типа Shape, в которой все свойства могут принимать значения NULL, и служебный тип ReadonlyShape для создания версии типа Shape, доступной только для чтения.

Заключение

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

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

Дополнительные материалы на PlainEnglish.io.

Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .

Заинтересованы в масштабировании запуска вашего программного обеспечения? Ознакомьтесь с разделом Схема.