Ответ
В статически типизированных языках (TypeScript, Rust, Haskell) union types позволяют определять переменные, которые могут хранить значения разных типов.
Основные виды:
-
Простое объединение (Untagged Union) Переменная может быть одного из нескольких типов, но у системы типов нет информации для их автоматического различения.
let id: string | number; id = "abc123"; // OK id = 123; // OK // Для использования нужна проверка типа (type guard) if (typeof id === 'string') { console.log(id.toUpperCase()); } -
Размеченное объединение (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).