Skip to content

Const enums are preserved when using transpileModule #5243

Closed

Description

@mbardauskas

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;

Activity

  1. vladima commented on Oct 13, 2015

    @vladima
    Contributor

    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
  2. mbardauskas commented on Oct 13, 2015

    @mbardauskas
    Author

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

  3. vladima commented on Oct 13, 2015

    @vladima
    Contributor

    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

  4. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    By DesignDeprecated - use "Working as Intended" or "Design Limitation" instead

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions