TypeScript and Backbone / Sinon Gotchas

Over the past few days I have been working through Jim Newbery’s excellent tutorial on testing Backbone applications with Jasmine and Sinon.

I just wanted to share a few gotcha’s that I experienced where TypeScript differs slightly from standard JavaScript.

1. Backbone default properties

Consider the following code:

var TodoListView = Backbone.View.extend({
    tagname: 'ul',
    className: 'todos'
});

The TypeScript equivalent would be the following:

class TodoListView extends Backbone.View {
    tagname: string = 'ul';
    className: string = 'todos';
}

Unfortunately, once the class is created, the tagname: and className: properties will be undefined.

Solution:

Set any default properties in the constructor:

class TodoListView extends Backbone.View {
    tagname: string;
    className: string;
    constructor (options?: any) {
        this.tagname = 'ul';
        this.className = 'todos';
        super(options);
    };
}

2. Backbone.Model setting attributes from default:

Consider the following JavaScript:

var Todo = Backbone.Model.extend({
    defaults: {
        'priority': 3
    }
});

In TypeScript, this should be written as:

class Todo extends Backbone.Model {
    defaults: {
        id: 0,
        priority: 0
    };
}

However, this will not compile, and generates the following error:

Expected type name

Solution :

defaults: any = {
                id: 0,
                priority: 0
        };

Note :

The official Microsoft release includes a solution that looks very convoluted :

class Todo extends Backbone.Model {
    initialize() {
        if (!this.get('id')) {
            this.set({ 'id': this.defaults().id });
        }
        if (!this.get('priority')) {
            this.set({ 'priority': this.defaults().priority });
        }

    };
    defaults() {
            return {
                id: 0,
                priority: 0,
            }
        };
}

3. Returning JSON responses with sinon.FakeServer.

Consider the following standard JavaScript code:

this.server.respondWith("GET", "/collection",
    [200, {"Content-Type": "application/json"},'{"id":123,"title":"Hollywood - Part 2"}']);

Unfortunately, this will generate an error message as follows.

Incompatible types in array literal expression

As far as I understand, this is due to mixing types in an array – which by TypeScript standards is not allowed.

Note that 200 is a number, {“Content-Type”: “application/json”} is an Object, and ‘{“id”… is a string.

Solution:

The only way that I have found around this is to drop the JSON return code and content type, and return just the string:

this.server.respondWith("GET", "/collection", JSON.stringify(this.fixture));

Have fun.

Advertisements

2 Responses to TypeScript and Backbone / Sinon Gotchas

  1. Sigfried says:

    The defaults:any solution does not work in the current version of typescript. The microsoft solution using defaults() {} is the better option

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: