Backbone.View definition


The definition of Backbone.View in todos.ts sample is as follows:
   export class View {
       constructor (options? );
       $(selector: string): any;
       el: HTMLElement;
       $el: any;
       model: Model;
       remove(): void;
       delegateEvents: any;
       make(tagName: string, attrs? , opts? ): View;
       setElement(element: HTMLElement, delegate?: bool): void;
       tagName: string;
       events: any;

       static extend: any;
model is set to be of type Backbone.Model however, in Backbone.js the 'class type' extending Backbone.Model is assigned to the model property and not an instance of Backbone.Model. Backbone will take care of the instatiation of the type. So I guess the correct definition should be something like:
       model: ()=>Model;
but that still creates compiler error. How is it possible to define this?
       model: class A where A extends Backbone.Model; // generics?
Closed Feb 6, 2013 at 4:43 PM by paulb
Closing this issue as it's more a question/discussion.

Yes, generics will help here.


omidkrad wrote Feb 5, 2013 at 5:16 PM

The following can bypass the compiler error for now but it still needs to be more specific.
       model: Function;
If it's not supported yet I would suggest the following syntax:
       model: <Model>;

omidkrad wrote Feb 6, 2013 at 11:39 PM

This issue was copied from a discussion, but it is not specific to Backbone.js and is a common issue that should be addressed in the specification.

omidkrad wrote Aug 6, 2013 at 8:40 PM

Related issue on DefinitelyTyped.

Maybe the solution for this is the new typeof operator?

omidkrad wrote Aug 7, 2013 at 12:58 AM


I initially tried the following:
class View<TModel extends Model> extends Events {
    model: TModel;
but this means model accepts instances of TModel not the type of TModel. Maybe the typeof operator in TypeScript 0.9.1 is just what we were looking for?


Can do model: typeof Model; but cannot use typeof of generic type like:
class View<TModel extends Model> extends Events {
    model: typeof TModel; // Error: Could not find symbol 'TModel'.

billti wrote Aug 7, 2013 at 2:16 AM

So are you asking that you want the class constructor, not the instance type, as the member? In that case, you could write something like the below:
class MyModel extends Model {
    myMembers: string[];
    static lastCreated: Date;

class View<T extends {new(): Model;}> extends Events {
    model: T;

var x = new View<typeof MyModel>();

x.model.lastCreated; // <- strongly typed, so includes the statics on MyModel
var y = new x.model(); // <- returns MyModel instance with 'myMembers' and base 'Model' members
Here I am using 'typeof' to pass the constructor type (not the instance type), and in the constraint specifying that is has to be a constructor that can new up models. Using generics however I'm able to preserve the strong typing such that the statics and members on my derived model class flow through.

Is this roughly what you wanted? Or did I misunderstand the requirement?

LukeH wrote Aug 7, 2013 at 3:34 AM

I also posted a reply on the DefinitelyTyped discussion of this same topic, suggesting another variant of what Bill suggests above: