I have very straightforward code:
enum Color { BLUE, RED }
class Brush {
color: Color
constructor(values) {
this.color = values.color
}
}
let brush = new Brush({ color: "BLUE" })
Now I want to make a check:
console.log(brush.color === Color.BLUE)
And it returns false
.
I tried a few combinations like
brush.color === Color[Color.BLUE]
But, of course, got a compiler error.
How to make quite a basic comparison enum === enum
?
I have very straightforward code:
enum Color { BLUE, RED }
class Brush {
color: Color
constructor(values) {
this.color = values.color
}
}
let brush = new Brush({ color: "BLUE" })
Now I want to make a check:
console.log(brush.color === Color.BLUE)
And it returns false
.
I tried a few combinations like
brush.color === Color[Color.BLUE]
But, of course, got a compiler error.
How to make quite a basic comparison enum === enum
?
3 Answers
Reset to default 7The problem is that TypeScript enum
s are actually "named numeric constants."
From the TypeScript documentation on enum
s:
Enums allow us to define a set of named numeric constants.
The body of an enum consists of zero or more enum members. Enum members have numeric value (sic) associated with them . . .
You should be using string literal types instead:
type Color = "BLUE" | "RED";
Full Code (View Demo):
type Color = "BLUE" | "RED";
class Brush {
color: Color
constructor(values) {
this.color = values.color
}
}
let JSON_RESPONSE = `{"color": "BLUE"}`
let brush = new Brush(JSON.parse(JSON_RESPONSE))
console.log(brush.color === "BLUE"); //=> true
An alternative (available since TS 2.4) is String enums:
enum Color {
BLUE = "BLUE",
RED = "RED"
}
console.log('BLUE' === Color.BLUE); // true
As there's no reverse mapping for string enums (at least in 2020), one might strongly consider inlining those with const
modifier.
This is possible, but requires you to create a type from the enum.
You can get a union type for all the keys in the enum by using:
<unionType> = keyof typeof <enum>
Here is the code demonstrating this modification:
enum Color { BLUE, RED }
type ColorType = keyof typeof Color; // 'BLUE' | 'RED'
type BrushValues = { color: ColorType } // Constructor args
class Brush {
color: Color
constructor(values: BrushValues) {
this.color = Color[values.color] // Lookup corresponding enum value
}
}
let brush = new Brush({ color: "BLUE" })
console.log(brush.color === Color.BLUE) // true
If you want to support any color, you will need some error-handling:
enum Color { BLUE, RED }
type ColorType = keyof typeof Color;
type BrushValues = {
color: string
}
class Brush {
color: Color
constructor(values: BrushValues) {
this.color = this.typeToEnum(values.color)
}
private typeToEnum(color: string): Color {
switch (color.toUpperCase()) {
case "BLUE": return Color.BLUE
case "RED": return Color.RED
default: throw new Error(`Invalid color: ${color}`)
}
}
}
try {
let brush = new Brush({ color: "YELLOW" })
} catch (e) {
if (e instanceof Error) {
console.error(`Could not create brush. ${e.message}`)
}
}
0
in this case so of course it returns false – O-9 Commented May 24, 2024 at 11:37