23

Similar to this question, but with the enumeration marked as a constant: How do you go about iterating or producing an array of from the const enum?

Example

declare const enum FanSpeed {
    Off = 0,
    Low,
    Medium,
    High
}

Desireable Results

type enumItem = {index: number, value: string};
let result: Array<enumItem> = [
    {index: 0, value: "Off"}, 
    {index: 1, value: "Low"}, 
    {index: 2, value: "Medium"}, 
    {index: 3, value: "High"}
];

2 Answers 2

12

No, this is not possible with a const enum. Let's start with your original enum and log one of its values:

const enum FanSpeed {
    Off = 0,
    Low,
    Medium,
    High
}

console.log(FanSpeed.High);

The TypeScript compiler inlines all the references to FanSpeed, and compiles the above code into something like this:

console.log(3 /* High */);

In other words, since you're using a const enum, no FanSpeed object actually exists at run time, just simple numeric literals are passed around instead. With a regular, non-const enum, a FanSpeed would exist as a value and you could iterate over its keys.

Edit: If you can change the compiler settings of your project, see Titian's answer below for very useful information about the preserveConstEnums flag, which will cause a FanSpeed object to actually be created and thus give you a way to iterate over your enum.

Sign up to request clarification or add additional context in comments.

6 Comments

Is is possible to preserve the const enum using the preserveConstEnums compiler flag
Yes, that's very important to mention @TitianCernicova-Dragomir. I linked to your answer from my answer so that they see what you wrote about preserveConstEnums
I tried setting "preserveConstEnums": true in the tsconfig.json file for my project, but syntax highlighting still highlights an error when using either of the examples in the referenced SO question. I'm using Visual Studio Code and I'm not sure what other settings need to be applied.
@Jim as I mentioned in my answer with the preserveConstEnums the enum object is there but it is a bit tricky to access because the compiler insists it does not exist.
@TitianCernicova-Dragomir, yeah, I'm digesting that now, in fact. My enum is placed in an interfaces.d.ts file along with many other interfaces and enums. Reading your post below and trying to decipher the right combination to reference that particular enum in the for loop.
|
7

You can use the preserveConstEnums compiler flag. This will emit the enum object in the Javascript but replace all values. The problem is that you can't for over the properties in a simple way because Typescript generates an error (enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment.). There are ways to get around it but it depends on your environment. Using modules you could write it like this:

import  * as e from "./enumModule"

for(var prop in (e as any)['FanSpeed']) {
  console.log(prop) ;
}

Or using a namespace you could do it like this:

namespace Enums { 
    export const enum FanSpeed {
        Off = 0,
        Low,
        Medium,
        High
    }
}
for(var prop in (Enums as any)['FanSpeed']) {
    console.log(prop) ;
}

Note: In either case you must use the preserveConstEnums compiler option first,

1 Comment

Does the compiler flag need to be used on the module which defines the enums, or the module which consumes the enums, or both? What if the enums are imported from another project -- if not, might it work if you [re]export them from a module of your own?

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.