Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript modules

I am wondering if it is possible somehow to have two or more classes in two or more files added to the same module in TypeScript. Something like this:

//src/gui/uielement.ts
module mylib {
    module gui {
        export interface UIElement {
            public draw() : void;
        }
    }
}

//src/gui/button.ts
///<reference path='uielement.ts'/>
module mylib {
    module gui {
        export class Button implements UIElement {
            constructor(public str : string) { }
            draw() : void { }
        }
    }
}

There will probably be dozens of GUI classes, so having them all in the same file will not be possible. And all my classes will be in the 'mylib' module. But how do I do that?

If the module mylib {...} is translated into a function then all content of all mylib blocks in all files should be contained within the same function.

Is this at all possible?

When I compile I get this:

$ tsc src/gui/button.ts 
src/gui/button.ts(4,39): The name 'UIElement' does not exist in the current scope
like image 766
Robert Larsen Avatar asked Oct 20 '12 18:10

Robert Larsen


1 Answers

This is exactly how it works! If you look at the generated javascript code, it add as an anonymous function that accepts an object, the "the module object":

var mylib;
(function (mylib) {
    var Button = (function () {
        function Button(x) {
            this.x = x;
        }
        return Button;
    })();
    mylib.Button = Button;    
})(mylib || (mylib = {}));

If you look at the last line (})(mylib || (mylib = {}));) you see that it instantiates a new ojbect (mylib = {}) only if the existing variable is false (or something that evaluates to false, like null). That way, all "modules" that are named the same will be merged to the same object.

Therefore, internal modules extend each other. I have to note that I have not quite figured out what happens to nested modules.

Update: Your code works for me if I do not use the nested module syntax, but change it to the dot syntax. e.g.:

module mylib.gui {
}

instead of

module mylib {
    module gui {
    }
}

I'll try to investigate in why this is happening, as far as I have read the spec, both ways should be equal.

Update: if the nested referenced module is marked as exported, it works:

module mylib {
    export module gui {
    }
}
like image 68
Philipp Aumayr Avatar answered Sep 19 '22 17:09

Philipp Aumayr