21

Enum definition:

enum Colors {
  Red = "red",
  Blue = "blue"
}

How can I cast some arbitrary sting (e.g. a result from a GET request) to the enum?

const color: Colors = "blue"; // Gives an error

In addition, why do integer enums work but string enums fail to have the same behavior?

enum Colors {
  Red = 1,
  Blue
}

const color: Colors = 1; // Works
Dylan Kerler
  • 2,007
  • 1
  • 8
  • 23
  • already answered, please check those answers: [Create an enum with string values](https://stackoverflow.com/questions/15490560/create-an-enum-with-string-values) [Cannot assign a string value to typescript enum (Initializer type string not assignable to variable type)](https://stackoverflow.com/questions/50464141/cannot-assign-a-string-value-to-typescript-enum-initializer-type-string-not-ass) – Fawzi Jul 09 '20 at 18:52
  • The accepted answer on that post is contradictory. The first way tells you how to access the enum value with the key which is not what i asked. The second way seems to work though. – Dylan Kerler Jul 09 '20 at 18:57

1 Answers1

31

If you are sure that the strings will always correspond to an item in the enum, it should be alright to cast it:

enum Colors {
  Red = "red",
  Blue = "blue",
}

const color: Colors = <Colors> "blue";

It won't catch the cases where the string is not valid. You would have to do the check at runtime:

let colorName: string = "blue"; // from somewhere else
let color: Colors;
if (Object.values(Colors).some((col: string) => col === colorName))
  color = <Colors> colorName;
else
  // throw Exception or set default...
JCOC611
  • 19,111
  • 14
  • 69
  • 90
  • 2
    Thanks. Why does integer enum work off the bat but string enum does not work unless you cast to the type? – Dylan Kerler Jul 09 '20 at 19:03
  • 1
    I cannot test right now but I quiet sure the `in` operator will check for the keys of the enum, not the values. In the example, `"blue"` will throw but `"Blue"` will pass. Number-based enums generates a reverse mapping but string-based ones does not. – Daniel Jul 10 '20 at 04:26
  • 5
    For some reason, with this type of casting I keep getting the error: "JSX element 'Colors' has no corresponding closing tag", so I had to do the casting in a different way to make it work: color = colorName as Colors – Pepe Alvarez Aug 05 '21 at 21:27
  • In above code, change `.some(...` to `.find(...` so that it stops iterating through enum values if it finds the correct one. – user358041 Mar 21 '23 at 13:38