Enumerations can conceptually be considered as a subset of union types allocated for values โโof type int
and / or string
, with some additional functions mentioned in other answers that make them convenient to use.
But the listings are not entirely safe:
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'
Union types support heterogeneous data and structures, including polymorphism, for example:
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(); }
I tend to look at F # to see good modeling practices. A quote from F # is for fun and profit, which may be useful here:
In general, you should give preference to delimited types of joins rather than enums, unless you need to have an int
(or string
) value associated with them.
source share