Какие виды объединений (union types) существуют в системах типов?

«Какие виды объединений (union types) существуют в системах типов?» — вопрос из категории Базы данных и SQL, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В статически типизированных языках (TypeScript, Rust, Haskell) union types позволяют определять переменные, которые могут хранить значения разных типов.

Основные виды:

  1. Простое объединение (Untagged Union) Переменная может быть одного из нескольких типов, но у системы типов нет информации для их автоматического различения.

    let id: string | number;
    id = "abc123"; // OK
    id = 123;       // OK
    // Для использования нужна проверка типа (type guard)
    if (typeof id === 'string') {
      console.log(id.toUpperCase());
    }
  2. Размеченное объединение (Tagged/Discriminated Union) Каждый вариант объединения имеет общее поле-дискриминатор (тег), что позволяет системе типов однозначно определить тип.

    type Shape =
      | { kind: 'circle'; radius: number }    // Тег 'circle'
      | { kind: 'square'; side: number }      // Тег 'square'
      | { kind: 'rectangle'; width: number; height: number };
    
    function getArea(shape: Shape): number {
      // TypeScript понимает тип по полю 'kind'
      switch (shape.kind) {
        case 'circle':
          return Math.PI * shape.radius ** 2; // Доступно shape.radius
        case 'square':
          return shape.side ** 2; // Доступно shape.side
        case 'rectangle':
          return shape.width * shape.height;
      }
    }

Практическая польза: Размеченные объединения исключают ошибки времени выполнения, обеспечивая полную проверку типов на этапе компиляции и устраняя необходимость в приведениях типов (type casting).