exported enums won't compile with tsickle/closure

238 views Asked by At

I am trying to compile an angular project with the new tsickle/closure chain. However, it seems to have to following errors on all enums:

src/path/to/YourEnumType.ts:1: ERROR - Exports must be a statement at the top-level of a module

My code is this:

export enum YourEnumType {
    None = 0,
    OneThing = 1,
    OtherThing = 2
}

How could I deal with this problem?

2

There are 2 answers

0
peterh On BEST ANSWER

The Typescript compiler generates from exported enums this:

var YourEnumType;
(function (YourEnumType) {
    YourEnumType[YourEnumType["None"] = 0] = "None";
    YourEnumType[YourEnumType["OneThing"] = 1] = "OneThing";
    YourEnumType[YourEnumType["OtherThing"] = 2] = "OtherThing";
})(YourEnumType = exports.YourEnumType || (exports.YourEnumType = {}));

As we can see, yes, this generated Javascript uses the exports from inside a function.

Digging into the typescript compiler, trying to play with its generated output format, and so on, I've found no way to work around this. Despite that, this Typescript code would be much better if it would be compiled as we can see in this answer:

var YourEnumType = Object.freeze({"None":1, "OneThing":2, "OtherThing":3, ...});

Unfortunately, typescript doesn't do this.

Similar digging in the google closure compiler show that there is no way to work around this without modifying the google closure source code.

Thus, considering this, and other major problems with enums in the whole typescript world, I think the only way out is to avoid using typescript enums.

0
Ruben On

If you pull the export to a separate line, then it works. I.e:

enum YourEnumType {
    None = 0,
    OneThing = 1,
    OtherThing = 2
}
export {YourEnumType};

Seems like a bug in tsickle.

Update: Also, since you use a minifier, you should consider const enums, which emit less code, and have fewer corner cases when used with closure:

const enum YourEnumType {
    None = 0,
    OneThing = 1,
    OtherThing = 2
}
export {YourEnumType};