Const enums are preserved when using transpileModule
mbardauskas opened this issue · 3 comments
It seems that using tsc
from command line and calling ts.transpileModule
in node provides different results: transpileModule preserves const enums. Whole reproduction source can be found here: https://github.com/mbardauskas/transpile-repro
file enums.d.ts:
declare const enum FooType {
Foo = 1,
Bar = 2,
}
file foo.ts:
/// <reference path="enums.d.ts" />
interface IFoo {
foo: FooType;
}
class FooClass {
public type: FooType;
constructor(obj: IFoo) {
this.type = obj.foo;
}
}
export function test() {
var foo = new FooClass(<IFoo>{
foo: FooType.Foo
});
console.log(foo.type);
}
Using typescript transpileModule to compile file source
var transpiled = ts.transpileModule(inputSource, {
reportDiagnostics: true,
compilerOptions: {
target: ts.ScriptTarget.ES5,
module: ts.ModuleKind.CommonJS,
preserveConstEnums: false
}
});
Output from tsc:
/// <reference path="enums.d.ts" />
var FooClass = (function () {
function FooClass(obj) {
this.type = obj.foo;
}
return FooClass;
})();
function test() {
var foo = new FooClass({
foo: 1 /* Foo */
});
console.log(foo.type);
}
exports.test = test;
Output from transpileModule:
/// <reference path="enums.d.ts" />
var FooClass = (function () {
function FooClass(obj) {
this.type = obj.foo;
}
return FooClass;
})();
function test() {
var foo = new FooClass({
foo: FooType.Foo
});
console.log(foo.type);
}
exports.test = test;
this behavior is by design. transpileModule
generally operates on the source code of the single file (in your case foo.ts
) and have not access to other files (enums.d.ts
). Because of that for this scenario we don't use type-directed emit because in most cases compiler does not have complete information on hands. I.e. in your case compiler have no idea what is the type of FooType
and that FooType.Foo` is actually a const enum and its value should be inlined.
More specifically in transpileModule
:
- imports\exports are not elided just because they cannot be resolved (since we have code for only one file)
const
enums are treated as regular enums (even for locally definedconst
enums)- files are always emitted as modules even if they don't have top level
export
\import
\require
Is there a way then to pass d.ts
files or source string for transpileModule
so the const enums would get inlined?
If multiple files are compiled at once how it is different from normal compilation? You can use minimal compiler sample from the Wiki to see how it can be achieved using compiler API