maxfridbe
maxfridbe

Reputation: 5970

Typescript module as namespace

If I have one file with two types in two different namespaces. The generated order matters.

export module Shapes {

    export module Weird{
        export class weirdshape extends Normal.normalshape{
            public x = 3;
        }
    }
    export module Normal{
        export class normalshape {
            public y = 4;
        }
    }
}

This will generate

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
define(["require", "exports"], function(require, exports) {
    (function (Shapes) {
        (function (Weird) {
            var weirdshape = (function (_super) {
                __extends(weirdshape, _super);
                function weirdshape() {
                    _super.apply(this, arguments);
                    this.x = 3;
                }
                return weirdshape;
            })(Normal.normalshape);
            Weird.weirdshape = weirdshape;
        })(Shapes.Weird || (Shapes.Weird = {}));
        var Weird = Shapes.Weird;
        (function (Normal) {
            var normalshape = (function () {
                function normalshape() {
                    this.y = 4;
                }
                return normalshape;
            })();
            Normal.normalshape = normalshape;
        })(Shapes.Normal || (Shapes.Normal = {}));
        var Normal = Shapes.Normal;
    })(exports.Shapes || (exports.Shapes = {}));
    var Shapes = exports.Shapes;
});

In this order this will fail. Because the Shapes.Normal.normalshape has not yet been defined.

Is there a proper way to do this in typescript where modules can be used as proper namespaces?

Upvotes: 2

Views: 1509

Answers (1)

Fenton
Fenton

Reputation: 250842

So if the question is "how do I make this code run", the answer is to do this:

export module Shapes {
    export module Normal{
        export class normalshape {
            public y = 4;
        }
    }

    export module Weird{
        export class weirdshape extends Normal.normalshape{
            public x = 3;
        }
    }
}

This isn't really a limitation of TypeScript - it is a limitation of JavaScript. If you use something before it is declared, you get problems.

You could argue that TypeScript should sort out the order for you, given it could work out the dependency. In actual fact, it will do this if you have separate files. For example, if Normal is in Normal.ts and Weird is in Weird.ts, the generated output will be ordered correctly for you.

Complete example:

Weird.ts

/// <reference path="Normal.ts" />

module Shapes {
    export module Weird {
        export class weirdshape extends Shapes.Normal.normalshape {
            public x = 3;
        }
    }
}

Normal.ts

module Shapes {
    export module Normal {
        export class normalshape {
            public y = 4;
        }
    }
}

app.ts

/// <reference path="Weird.ts" />
/// <reference path="Normal.ts" />

var weird = new Shapes.Weird.weirdshape();

Compiled using --out final.js - resulting final.js:

var Shapes;
(function (Shapes) {
    (function (Normal) {
        var normalshape = (function () {
            function normalshape() {
                this.y = 4;
            }
            return normalshape;
        })();
        Normal.normalshape = normalshape;
    })(Shapes.Normal || (Shapes.Normal = {}));
    var Normal = Shapes.Normal;
})(Shapes || (Shapes = {}));
var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var Shapes;
(function (Shapes) {
    (function (Weird) {
        var weirdshape = (function (_super) {
            __extends(weirdshape, _super);
            function weirdshape() {
                _super.apply(this, arguments);
                this.x = 3;
            }
            return weirdshape;
        })(Shapes.Normal.normalshape);
        Weird.weirdshape = weirdshape;
    })(Shapes.Weird || (Shapes.Weird = {}));
    var Weird = Shapes.Weird;
})(Shapes || (Shapes = {}));
var weird = new Shapes.Weird.weirdshape();

Upvotes: 1

Related Questions