microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.99k stars 12.48k forks source link

Use string type(JS) when compile enum type(TS) #17527

Closed Aqours closed 7 years ago

Aqours commented 7 years ago

TypeScript Version: 2.4.2

Code

export enum PlayOrderEnum { Positive, Reverse, Random }
if (PlayOrderEnum.Reverse) {
    console.log('good');
} else {
    console.log('bad');
}

Expected behavior:

// Compiled code (ES5)
(function (PlayOrderEnum) {
    PlayOrderEnum[PlayOrderEnum["Positive"] = 0] = "Positive";
    PlayOrderEnum[PlayOrderEnum["Reverse"] = 1] = "Reverse"; // [1]
    PlayOrderEnum[PlayOrderEnum["Random"] = 2] = "Random";
})(exports.PlayOrderEnum || (exports.PlayOrderEnum = {}));
// Use PlayOrderEnum["Reverse"] instead of PlayOrderEnum.Reverse
// If we compress property of object, PlayOrderEnum.Reverse will be transformed.
// But [1]'s 'Positive' will be always string type
if (PlayOrderEnum["Reverse"]) {
    console.log('good');
} else {
    console.log('bad');
}

Actual behavior:

// Compiled code (ES5)
(function (PlayOrderEnum) {
    PlayOrderEnum[PlayOrderEnum["Positive"] = 0] = "Positive";
    PlayOrderEnum[PlayOrderEnum["Reverse"] = 1] = "Reverse";
    PlayOrderEnum[PlayOrderEnum["Random"] = 2] = "Random";
})(exports.PlayOrderEnum || (exports.PlayOrderEnum = {}));
if (PlayOrderEnum.Reverse) {
    console.log('good');
} else {
    console.log('bad');
}
shivensinha4 commented 7 years ago

You could try changing the TS code to
if (PlayOrderEnum["Reverse"]) { console.log('good'); }

Aqours commented 7 years ago

@shivensinha4 You are right. But without advantage of code insight

RyanCavanaugh commented 7 years ago

It's not TypeScript's job to guess around at what your minifier might be doing.

Aqours commented 7 years ago

@RyanCavanaugh I think that the fake key in enum is string type, so compiled code should be string type, which is not relative to minifier. enum is not object, so PlayOrderEnum['Reverse'] is better than PlayOrderEnum.Reverse.

shivensinha4 commented 7 years ago

@Aqours Sure, if that happens to be your opinion. But a compiler must give the programmer the maximum amount of control of the output. Say, if you wanted the transpiled code to have foo.bar in it, maybe due to the the specific style of code of your project, and if the compiler always converts it into foo['bar'], wouldn't it be frustrating? The current behaviour of the compiler allows both the options.