Tuesday, September 9, 2014

Revisiting AngularJS with TypeScript

Many of my recent blog posts and presentations have focused on pure JavaScript. I believe TypeScript is an incredibly useful tool, especially when developing heavy client apps with large teams. I don’t use it in most examples so they stay relevant to developers who haven’t adopted it. TypeScript is a strong asset for AngularJS apps. I was recently asked about my Angular app structure using TypeScript, so I developed a small example.

In my recent talk about Advanced AngularJS Tips and Tricks, I provided a fairly interactive example using a list of pictures with a selection. The purpose was to demonstrate the controller as syntax and show that you can accomplish what is needed without depending on explicit watchers. You can browse the source; the controllers, etc. are underneath the “01” subfolders.

The first step to developing apps in TypeScript is to pick up any related definition files. I use a repository called definitely typed. There are definitions for most of the common libraries, including Angular. What’s more, you can also install it in your Visual Studio projects using NuGet.

After I have the type definitions in my project, I define an application module. The module encapsulates the functionality and avoids naming collisions. I should give you the caveat that the Google best practices dictate you should always reference your modules by calling angular.module with the module name (after you’ve defined the module by passing in dependencies), rather than trying to capture a global reference. Personally I don’t have an issue retaining the reference when I am already creating a module scope for the app, so I choose to use it.

declare var angular: ng.IAngularStatic;
module Application {
    "use strict";
    export var angularApp: ng.IModule =
        angular.module("angularApp", ["ngAnimate"]);

The code takes advantage of the definitely typed library to define the angular static type. This gives me IntelliSense/auto-completion and development-time checking of the functional calls I’ll be making. The only real code generated is the scoped reference to the current module contained in the angularApp variable. The generated code looks like this:

var Application;
(function (Application) {
    "use strict";
    Application.angularApp = angular.module(
        "angularApp", ["ngAnimate"]);
})(Application || (Application = {}));

The next logical component to define is the data. For the data I do two things. First, I export an interface to make it easier to deal with the later elsewhere in the app. This will provide discovery and development-time type checking. Second, I create a function to encapsulate the definition before I pass it to Angular. This closure prevents the data from “leaking” to the rest of the app (and potentially colliding or further dirtying the logical namespaces), so after the call the only way to reference it is through the Angular dependency. I truncated the list for the sake of display:

module Application {
    "use strict";
    export interface ISunsetData {
        image: string;
        location: string;
        title: string;
    function initData(): void {
        var data: ISunsetData[] = [
                image: "backyard.jpg",
                location: "Woodstock, GA",
                title: "Sunset in Woods"
        angularApp.value("sunsets", data);


After the data is defined, I wrap it in a service. The service exposes a filter that controllers can use, and provides a “selected item” used to render the full size picture. Notice that in TypeScript I can expose a contract for the service without exposing the service itself. The class for the service is not exported, so it is only available for registration with Angular. When I reference it, I use the interface.

module Application {
    "use strict";
    export interface ISunsetService {
        sunsets: ISunsetData[];
        selected: ISunsetData;
        filter: string;
        select: (sunset: ISunsetData) => void;
    class SunsetService implements ISunsetService {
            public sunsets: ISunsetData[],
            public $log: ng.ILogService) {

            $log.log("Sunsets service created.");
        public selected: ISunsetData;
        public filter: string;
        public select(sunset: ISunsetData): void {
            this.$log.log("Selected sunset "
                + sunset.title);
            this.selected = sunset;
    angularApp.service("sunsetSvc", [
        "sunsets", "$log", SunsetService]);

In this example, I register the service using the variable I set up in the main app to reference the module. I also am using the registration-time version of dependency injection since I am registering the class the same time I define it. If I were using a system to define the class and then register it elsewhere, I’d use the static $inject: string[] signature instead so the dependencies are easily discoverable.

I don’t have any need to expose the definition for the controller to the rest of the application, so I simply define the class without exporting it and register it with Angular. I use the exported contracts to bring properties into the constructor. Note how easy TypeScript makes it to define property getters and setters.

module Application {
    "use strict";
    class SearchController {
        private _filter:string;
            public $log: ng.ILogService,
            public sunsetSvc: ISunsetService) {
            this._filter = "";
            $log.log("Search controller created.");
        public get filter(): string {
            return this._filter;
        public set filter(val: string) {
            this.sunsetSvc.filter = val;
            this._filter = val;
    angularApp.controller("searchCtrl", ["$log", "sunsetSvc", SearchController]);

This is the generated JavaScript for the filter property:

    "filter", {
    get: function () {
        return this._filter;
    set: function (val) {
        this.sunsetSvc.filter = val;
        this._filter = val;
    enumerable: true,
    configurable: true

The list controller is similar. You can view the full source for the converted TypeScript project at this link. It is part of the original project, and only contains the TypeScript source files for simplicity.

As you can see, TypeScript works very well with AngularJS. The definition files help with exploring the API and ensuring it is used correctly at development time. Interfaces help describe structure and it is easy to contain them within defined modules or scopes. Although all of this is possible with pure JavaScript, the TypeScript language not only makes it easier to define these patterns, but also implements them in a consistent way.

Do you use TypeScript with AngularJS or are you considering it? If so, share your thoughts or questions in the comments below!


  1. Nice article Jeremy!
    I'm structuring the code a little bit differently.

    I have like you one file for one "part of module"

    For example:
    I have a resize module, which includes all related stuff ( so for this example only module declaration and directive).
    For better readability I define everything in "index.ts" for particular module like this:

    resize.ts ( index )
    module lbw.com.resize {
    'use strict';

    export var module = angular
    .module('lbw.com.resize', [
    .directive('lbwResize', lbwResize);

    module lbw.com.resize {
    'use strict';

    export var lbwResize = (
    $window: ng.IWindowService,
    $document: ng.IDocumentService,
    $rootScope: ng.IRootScopeService,
    $timeout: ng.ITimeoutService,
    dimensions: ng.strap.IDimensions): ng.IDirective => {

    var linkFn = function (scope: ng.IScope, element: JQuery, attrs: any) { .... };
    return {
    restrict: 'A',
    link: linkFn


    lbwResize.$inject = [


    so if an user will come to index of a particular module, he immediately knows what's included in it.

    only caveat is, you have to watch out for script order in html or via typescript reference tags (in some mainApp.ts file for example), so the (index) file has to be always the last in the order.

    reference path="components/resize/resize-directive.ts"
    reference path="components/resize/resize.ts"

    So in the end the overall include to main angular app is like this:

    module lbw.app {
    'use strict';

    .module('myApp', [ com.resize.module.name ])


  2. Thanks for the detailed comment! Typically I've just managed this based on the modules being located in folders, so the "registry" is easily browsed by looking at files in the folder. I mentioned in the talk one convention isn't necessarily better, but you need to have one. In your case you have a well known file that indexes the services, in my case I use the folder structure and names to provide that reference. Either way TypeScript will provide completion and IntelliSense from within the IDE.

  3. Do you think Typescript will run it's course with ECMASCRIPT 6 and the ability to create classes? I was going this route for an MVC application, then read about ECMA 6. http://en.wikipedia.org/wiki/ECMAScript

    Any thoughts?

  4. What do you mean by "run it's course?" My understanding is they'll keep it closely aligned and it's very close already. There is a discussion about it here:


    Does that answer your question?