50

It seems that from TypeScript 2.4 onwards String Enums are a feature.

However the following does not work:

enum Foo {
    A = "A",
    B = "B"
}

var foo : Foo = "A";

Initializer type string not assignable to variable type Foo

String literals work:

type Foo = "A" | "B";

But what if I want to use an enum? Is there a way around this?

1
  • 3
    it seems to me that no answer provides explanation to why this won't work. From a similar issue on github: "The intent of string enums is that the values of the enum are opaque (i.e. they can be changed behind the scenes without breaking consumers). If you don't want that behavior, it's easy enough to use the pre-string-enum workarounds to create similar union types. Numeric enums allow assignments from arbitrary numbers because we need to support bitflag enums and the | / & / etc operators return number. There's no corresponding behavior for string enums that needs to be supported." Commented Dec 2, 2022 at 9:51

4 Answers 4

30

You can use an index expression to get the value of the enum:

enum Foo {
    A = "A",
    B = "BB"
}

var foo : Foo = Foo["A"];
var fooB : Foo = Foo["B"];

Note that the key will be the name of the member not the value.

You could also use a type assertion, but you will not get errors if you assign a wrong value:

var foo : Foo = "A"  as Foo;
var foo : Foo = "D"  as Foo; // No error
Sign up to request clarification or add additional context in comments.

2 Comments

Though you won't get compile errors on attempt to use a value that does not exist in this enum with such approach
This won't work if enum is private and never exposed. Need a better solution for tests.
19

As Foo is the enum so you can use the . as well to accesss the value of enum like below

var foo : Foo = Foo.A;

Comments

8

While not a direct answer to the question per se (as it doesn't assign to enum but a derivative type), I discovered this which does solve my problem of allowing me to assign a string and guarantees that it's a part of the enum, and even allows me to avoid the redundant A = "A" when all that really matters is A.

You can use keyof [1] to enumerate the properties on the typeof the enum (Foo)

enum Foo {
    A,
    B
}

var foo : keyof typeof Foo = "A"; // OK
var foo : keyof typeof Foo = "C"; // ERROR

Or on objects:

interface Bar {
    type: keyof typeof Foo
}

let obj: Bar = {
    type: "A" // OK
}

[*] I'll mark one of the other answers as accepted and keep this here for reference

Comments

7

As described into the typescript enum documentation

you can use it in different ways :

Enum.A // Good way

Enum["A"] // Bad way

Enum[variable] // Good way

In your case

enum Foo {
    A = "A",
    B = "B"
}

// Bad way
const example1 : Foo = Foo["A"];

// Good way
const example2 : Foo = Foo.A;

// Good way
const example3 : Foo = Foo[variable];

You should AVOID the use of example1 and focus on example2 and example3. In any case, there is no point to write "A".

Always prefer Enum.A and if you want to cast a variable as an enum use Enum[variable].

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.