Initially, consider the following:
const BasicColor = {
Red: 1,
Green: 2,
Blue: 4
};
The values Red
, Green
, and Blue
can be changed (unlike in an enum).
Enums offer several advantages:
- a defined set of known values (to prevent mistakes later on), each with...
- a specific set of literal-like types for each member, all provided by...
- a single named type that covers all values
To achieve this with a namespace, you would need to do something like this:
export namespace Color {
export const Red = 1;
export type Red = typeof Red;
export const Green = 2;
export type Green = 2;
export const Blue = 3;
export type Blue = typeof Blue;
}
export type Color = Color.Red | Color.Blue | Color.Green;
There is also some old behavior in TypeScript where assignment from any number to a numeric enum is allowed.
However, if you use a string enum, this behavior does not occur. Additionally, there are other features such as exhaustiveness checking that can be enabled with union enums:
enum E {
Hello = "hello",
Beautiful = "beautiful",
World = "world"
}
function assertNever(x: never) {
throw new Error("Unexpected value " + x);
}
declare var x: E;
switch (x) {
case E.Hello:
case E.Beautiful:
case E.World:
// perform actions...
break;
default: assertNever(x);
}