Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript type checking - Backbone.Model instance cannot be type checked

I'm having a problem with Typescript and Backbone collections. Here's some groundwork:

class BaseChartModel extends Backbone.Model { }
class ScatterPlotModel extends BaseChartModel { }
class BarChartModel extends BaseChartModel { }

class MixedChartCollection extends Backbone.Collection { public model: BaseChartModel; ... }
class ScatterPlotCollection extends Backbone.Collection { public model: ScatterPlotModel; ... }
class BarChartCollection extends Backbone.Collection { public model: BarChartModel; ... }

Then I do the following:

 var scatterPlotCollection = new ScatterPlotCollection();
 var scatterPlotCollectionXhr = scatterPlotCollection.fetch({...});

 var barChartCollection = new BarChartCollection();
 var barChartCollectionXhr = barChartCollection.fetch({...});

 $.when(scatterPlotCollectionXhr, barChartCollectionXhr).done(() => {

       mixedCollection = new MixedChartCollection();
       mixedCollection.add(scatterPlotCollection.models, { silent: true });
       mixedCollection.add(barChartCollection.models, { silent: true });
       chartViewList = new MixedChartViewList({ collection: mixedCollection });

       chartViewList.render();

 });

Inside render():

public render(){
     var self = this;
     this.$el.html(this.template({}));

     this.collection.forEach(
    (chartModel: BaseChartModel) => {
            this.$el.append(self.AddChartView(chartModel).render());                  
    }
 );

     return this;
}

public AddChartView(baseChartModel: BaseChartModel) : BaseChartView {

      var newChartView: BaseChartView;

      if(baseChartModel instanceof ScatterPlotModel){
           newChartView = new ScatterPlotView({ model: baseChartModel});
      } else if (baseChartModel instanceof BarChartModel){
           newChartView = new BarChartView({ model: baseChartModel});
      } 
      ....       
}

Except instanceof never evaluates to true because it seems that the 'class type' deriving from Backbone.Model gets assigned to Backbone.Model.attributes rather than being an instance of the class itself. I believe this is because when implementing my classes that derive from Backbone.Model I followed this approach and it seems like it may be the reason for this problem. Basically it delegates get/set properties on the TS class to the underlying Backbone.model.get()/set() which in turn sets the values on the attributes property.

It seems I have to either drop this approach (and hope that was the problem) or figure out a way to do a loosely coupled type check similar to or using instanceof between the baseChartModel.attributes object and my class prototype for App.BackBone.Models.ScatterPlotModel

This breakpoint is at the line with instanceof comparison enter image description here

Any ideas?

like image 619
parliament Avatar asked Mar 05 '26 04:03

parliament


1 Answers

The approach that you are using seems valid enough. I have plugged the following code into the TypeScript playground just to check a few javascript symantics:

class A { }

class B extends A { }

class Checker {
    static isA(input: A) {
        return (input instanceof A);
    }
}

var a = new A();
var b = new B();

document.writeln('a instanceof A ' + (a instanceof A) + '<br/>');
document.writeln('b instanceof B ' + (b instanceof B) + '<br/>');
document.writeln('b instanceof A ' + (b instanceof A) + '<br/>');
document.writeln('b instanceof A (via function) ' + Checker.isA(b) + '<br/>');

var aArray : A[] = [];

aArray.push(a);
aArray.push(b);

for(var i = 0; i < aArray.length; i++) {
    document.writeln('aArray[' + i + '] instance of A ' + (aArray[i] instanceof A) + '<br/>' );
}

This gives the following output:

a instanceof A true 
 b instanceof B true 
 b instanceof A true 
 b instanceof A checker true 
 aArray[0] instance of A true 
 aArray[1] instance of A true 

This must mean that the call

mixedCollection.add( scatterPlotCollection.models, { silent: true });

is causing the problem here.
Possibly scatterPlotCollection.models is NOT returning your original objects ( i.e. ScatterPlotModel or BarChartModel ), and is instead just returning [Object object], hence the instance of is failing ?

Hope this helps,

like image 125
blorkfish Avatar answered Mar 06 '26 18:03

blorkfish



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!