最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Comparing value to enum isn't obvious in TypeScript - Stack Overflow

programmeradmin2浏览0评论

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?

Share Improve this question edited May 24, 2024 at 11:32 jonrsharpe 122k30 gold badges266 silver badges473 bronze badges asked Mar 25, 2017 at 2:02 fasthfasth 2,3427 gold badges27 silver badges39 bronze badges 1
  • well enum BLUE is just a alias for integer/numeric 0 in this case so of course it returns false – O-9 Commented May 24, 2024 at 11:37
Add a comment  | 

3 Answers 3

Reset to default 7

The problem is that TypeScript enums are actually "named numeric constants."

From the TypeScript documentation on enums:

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)

  1. 暂无评论