Typescript имеет союзы, поэтому перечислены избыточные?

С тех пор как TypeScript вводил типы союзов, мне интересно, есть ли причина объявлять тип перечисления. Рассмотрим следующее объявление типа перечисления:

enum X { A, B, C }
var x:X = X.A;

и подобное объявление типа объединения:

type X: "A" | "B" | "C"
var x:X = "A";

Если они в основном служат одной и той же цели, а профсоюзы более мощные и выразительные, то зачем нужны перечисления?

Ответ 1

Насколько я вижу, они не являются избыточными, по той простой причине, что типы объединения являются просто концепцией времени компиляции, тогда как перечисления фактически переносятся и заканчиваются в результирующем javascript (образце).

Это позволяет вам делать некоторые вещи с перечислениями, которые в противном случае невозможны с типами объединения (например, перечисление возможных значений перечисления)

Ответ 2

Есть несколько причин, по которым вы можете использовать enum

Я вижу большие преимущества использования объединения в том, что они предоставляют краткий способ представления значения несколькими типами, и они очень удобочитаемы. let x: number | string

РЕДАКТИРОВАТЬ: Начиная с TypeScript 2.4 Enums теперь поддерживает строки.

enum Colors {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE",
} 

Ответ 3

Перечисления могут концептуально рассматриваться как подмножество типов объединения, выделенных для значений типа int и/или string, с некоторыми дополнительными функциями, упомянутыми в других ответах, которые делают их удобными для использования.

Но перечисления не совсем безопасны:

enum Colors { Red, Green, Blue }
const c: Colors = 100; // No errors!

type Color =
    | 0 | 'Red'
    | 1 | 'Green'
    | 2 | 'Blue';

const c2: Color = 100; // Error: Type '100' is not assignable to type 'Color'

Типы объединения поддерживают разнородные данные и структуры, включая полиморфизм, например:

class RGB {
    constructor(
        readonly r: number,
        readonly g: number,
        readonly b: number) { }

    toHSL() {
        return new HSL(0, 0, 0); // Fake formula
    }
}

class HSL {
    constructor(
        readonly h: number,
        readonly s: number,
        readonly l: number) { }

    lighten() {
        return new HSL(this.h, this.s, this.l + 10);
    }
}

function lightenColor(c: RGB | HSL) {
    return (c instanceof RGB ? c.toHSL() : c).lighten();
}

Я склонен смотреть на F #, чтобы увидеть хорошие практики моделирования. Цитата из F # для удовольствия и прибыли, которая может быть полезна здесь:

В общем, вам следует отдавать предпочтение разграниченным типам объединений, а не перечислениям, если только вам не нужно иметь значение типа int (или string), связанное с ними.