Compiler module variable declaration

Topics: General
Aug 13, 2013 at 11:43 AM
Hi,

When compiling I came across something rather strange. When I compile using the --out option to output a single file, each referenced module is redeclared, resulting in the following:
var Wf;
(function (Wf) {
    (function (Model) {
        var User = (function () {
            function User(name) {
                this.name = name;
            }
            return User;
        })();
        Model.User = User;
    })(Wf.Model || (Wf.Model = {}));
    var Model = Wf.Model;
})(Wf || (Wf = {}));
var Wf;
(function (Wf) {
    (function (Model) {
        var Message = (function () {
            function Message(message) {
                this.message = message;
            }
            return Message;
        })();
        Model.Message = Message;
    })(Wf.Model || (Wf.Model = {}));
    var Model = Wf.Model;
})(Wf || (Wf = {}));
var Wf;
(function (Wf) {
    var App = (function () {
        function App() {
            this.User = new Wf.Model.User("Chris");
            this.User.Message = new Wf.Model.Message("This is my message!");
        }
        App.prototype.log = function () {
            console.log(this.User.name + ' says ' + this.User.Message.message);
        };
        return App;
    })();
    Wf.App = App;
})(Wf || (Wf = {}));
Is there a way to make the compiler recognise the module declarations that are the same and just create a single var for that particular module?

Below is the typescript code:
app.ts
///<reference path='Models/User.ts' />
///<reference path='Models/Message.ts' />
module Wf {
    export class App {
        
        User: Wf.Model.User;

        constructor(){
            this.User = new Wf.Model.User("Chris");
            this.User.Message = new Wf.Model.Message("This is my message!");
        }

        public log() {
            console.log(this.User.name + ' says ' + this.User.Message.message);
        }
    }
}
models/user.ts
module Wf {
    export module Model {
        export class User {
            name: string;
            Message: Message;
            constructor(name: string) {
                this.name = name;
            }
        }
    }
}
models/message.ts
module Wf {
    export module Model {
        export class Message {
            message: string;
            constructor(message: string){
                this.message = message;
            }
        }
    }
}
Aug 14, 2013 at 2:09 AM
Edited Aug 14, 2013 at 2:10 AM
As far as I understand:

While it looks a bit strange, it works just fine because of how javascript deals with declarations. Multiple var declarations in the same scope are just ignored.

This:
Wf || (Wf = {}) 
is a commonly used pattern, and tells the function to use the existing Wf object if it's not undefined, otherwise it sets Wf to an empty object and uses it.
Aug 14, 2013 at 9:32 AM
prgjonas wrote:
As far as I understand:

While it looks a bit strange, it works just fine because of how javascript deals with declarations. Multiple var declarations in the same scope are just ignored.

This:
Wf || (Wf = {}) 
is a commonly used pattern, and tells the function to use the existing Wf object if it's not undefined, otherwise it sets Wf to an empty object and uses it.
Thanks for your reply. This isn't exactly what I meant though.

I'm more concerned about the var Wf; declaration. When outputting to a single file it seems a bit redundant to have the variable declared three times (outside of the actual object scope) instead of just once.
Coordinator
Aug 14, 2013 at 2:15 PM
The current TypeScript compiler performs few, if any, optimizations. We've been focusing on getting the language implementation in there and making sure it's correct. In this case, I agree that it sounds like we could notice the --out during an optimization phase, and do the declaration merging before the code goes out. Sounds like a good candidate optimization for later.