user603563 user603563 - 6 months ago 24
Javascript Question

TypeScript - she's gotta have it? (where it == global scope)

I'm converting an Angular app to use TypeScript, but this is a general TypeScript question, not about Angular.
The angular js files are along the lines:

(function () {
var app = angular.module('myModule', []);
app.controller('myController', ['$scope',
function ($scope) {
$scope.myNewProperty = "Bob";
}
]);
})();


And I have converted that to lovely TypeScript class syntax:

class myController {
constructor($scope) {
$scope.myNewProperty = "Bob";
}
}

angular.module('myModule', []).controller("myController", myController);


All works fine, except the generated JS is not wrapped according to the JS module pattern (i.e. in an outer anonymous function):

var myController = (function () {
app.controller('myController', ['$scope',
function ($scope) {
$scope.myNewProperty = "Bob";
}
]);
})();

var app = angular.module('myModule', []);


So myController is now global. If I put the class in a TypeScript module, then the js generates with the module name as a global variable:

var TsModule;
(function (TsModule) {
var myController = (function () {
app.controller('myController', ['$scope',
function ($scope) {
$scope.myNewProperty = "Bob";
}
]);
})();

var app = angular.module('myModule', []);
})(TsModule || (TsModule = {}));


How do I stop TypeScript polluting the global scope in this way? I just want it all wrapped in a nice local scope.
I have seen it said elsewhere "just go back to the old JS syntax" (i.e. no TypeScript class).
How can I define an AngularJS service using a TypeScript class that doesn't pollute the global scope?

But the whole point of us using TypeScript /is/ the class syntax. Is TypeScript at odds with any (sensible) JS programmer who knows not to go global?

Answer

You can simply wrap your class inside a module

The module itself will be global, but if you don't export the class, there is little worry about polluting the global scope with a single module name.

So this TypeScript:

module MyModule {
  class MyClass {
     constructor(){}
  }
}

Will produce the following JS:

var MyModule;
(function (MyModule) {
    var MyClass = (function () {
        function MyClass() {
        }
        return MyClass;
    })();
})(MyModule || (MyModule = {}));