Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Const enums are preserved when using transpileModule #5243

Closed
mbardauskas opened this issue Oct 13, 2015 · 3 comments
Closed

Const enums are preserved when using transpileModule #5243

mbardauskas opened this issue Oct 13, 2015 · 3 comments
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead

Comments

@mbardauskas
Copy link

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;
@vladima
Copy link
Contributor

vladima commented Oct 13, 2015

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 defined const enums)
  • files are always emitted as modules even if they don't have top level export \ import \ require

@vladima vladima closed this as completed Oct 13, 2015
@vladima vladima added the By Design Deprecated - use "Working as Intended" or "Design Limitation" instead label Oct 13, 2015
@mbardauskas
Copy link
Author

Is there a way then to pass d.ts files or source string for transpileModule so the const enums would get inlined?

@vladima
Copy link
Contributor

vladima commented Oct 13, 2015

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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead
Projects
None yet
Development

No branches or pull requests

2 participants