简体   繁体   中英

Is there a way to create enums in typescript that are ambient?

edit after release of typescript 0.9: enums are now supported:

enum Select { every, first, last }

original question:

Enums in typescript were discussed here but no solution leads to an ambient design. An ambient enum definition would mean that the enum is handled by the compiler only and the compiled js output files only deal with the raw numerical values. Like in C++11.

The closest I get is

declare var Color = { red: 1, blue: 2, green: 3 } // DOES NOT COMPILE

but the compiler does not accept this: "Ambient variable cannot have initializer".

edit
incorporating dmck's answer:

declare var Color: { Red: number; Green: number; Blue: number; };

This does not output any js code. In other words, it is ambient. This however makes it useless as well:

declare var Color: { Red: number; Green: number; Blue: number; };

function test() {
  var x = Color.Blue;    // null ref exception, no Color object
  console.log(x == Color.Red);
}

will produce a runtime error, as Color is not defined in js. The ts declaration just claims that there is some Color object in js, while in fact, without definition, there is none. Ti fix this we can add

var Color = {
   Red: 1,
   Green: 2,
   Blue: 3
};

but now the enum implementation is not "ambient" in the sense that the typescript compiler does what a C++ compiler does, reducing the enum values at all occurencies to plain numbers. The current ambient declarations allow type checking but not such replacement.

TypeScript 0.9允许这样:

declare module A { export enum E { X, Y, Z } }

Adding an answer as there are new features for this starting with TypeScript 1.4;

using const enum give the expected result.

This is with a normal enum:

//TypeScript:
enum StandardEnum {FirstItem, SecondItem, ThirdItem};

//Compiled javascript:
var StandardEnum;
(function (StandardEnum) {
    StandardEnum[StandardEnum["FirstItem"] = 0] = "FirstItem";
    StandardEnum[StandardEnum["SecondItem"] = 1] = "SecondItem";
    StandardEnum[StandardEnum["ThirdItem"] = 2] = "ThirdItem";
})(StandardEnum || (StandardEnum = {}));

This is with a const enum:

//TypeScript:
const enum ConstantEnum { FirstItem, SecondItem, ThirdItem };

//Compiled javascript:
;

This blog post explains it with more details : https://tusksoft.com/blog/posts/11/const-enums-in-typescript-1-4-and-how-they-differ-from-standard-enums

You could do something like this:

declare var Color: { Red: number; Green: number; Blue: number; };

Remember that by design ambient declarations have no effect on the output of your code . So somewhere you'll need to actually declare Color and the values of each enum member.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM