Search code examples
javascriptbackbone.jstypescript

Backbone view can't use Backbone collection in typescript


I'm trying to create a Backbone view that is bound to a Backbone collection. But according to the definition file from DefinitelyTyped the Backbone view object can only take a model as it's generic type parameter. How can I bind the view to a collection?

My current code throwing the error:

export class EnvironmentMenu extends Backbone.View<EnvironmentCollection>{

constructor(options?: Backbone.ViewOptions<EnvironmentCollection>) {
         super(options);
    }
}

The error is Type 'EnvironmentCollection' does not satisfy the constraint 'Backbone.Model' for type parameter 'TModel extends Backbone.Model'

Which I'm assuming is because of this line in the definition:

class Collection<TModel extends Model> extends ModelBase

My models and collections are just shells at the moment

Environment model

export class EnvironmentModel extends Backbone.Model {
    constructor(options?) {
        super(options);
    }
}

Environment colleciton

export class EnvironmentCollection 
    extends Backbone.Collection<EnvironmentModel> {

    constructor(options?) {
        super(options);
        this.model = EnvironmentModel;
    }
} 

Solution

  • The answer to this was to basically wrap the collection in a seperate model, which in this specific scenario adds little extra value apart from compiling without errors, but I've actually found it handy to store additional information related to collection which are not already part of the collections properties.

    export class EnvironmentViewCollection extends Backbone.Model {
        constructor(collection: EnvironmentCollection, options?: any) {    
             options = options || {};
             options.innerCollection = collection;
        }
    
        getCollection() : EnvironmentCollection {
             return this.get('innerCollection');
        }
    }
    

    Then you can use that model in the view

    export class EnvironmentMenu extends Backbone.View<EnvironmentViewCollection> {
        constructor(options?: Backbone.ViewOptions<EnvironmentViewCollection>) {
            super(options);
        }
    
        useCollection() : void {
            var collectionLength = this.model.getCollection();
            console.log('The length of the collection is', collectionLength);
        }
    }