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

I have a problem with Typescript and Backbone collections. Here are some basics:

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 , true is never evaluated, because it seems that the class type obtained from Backbone.Model is assigned to Backbone.Model.attributes , and is not an instance of the class itself. I believe this is due to the fact that when implementing my classes that come from Backbone.Model, I followed this up and it looks like this might be causing this problem. This basically delegates the get / set properties of the TS class to the underlying Backbone.model.get () / set (), which in turn sets the values ​​in the attributes property.

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

This breakpoint is on line with instanceof comparison enter image description here

Any ideas?

+3
source share
2 answers

The approach you are using seems reasonable enough. I hooked up the following code on the TypeScript playground to check out a few javascript likes:

 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 result:

 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 

That means a challenge

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

causing the problem here.
Maybe scatterPlotCollection.models does not return your original objects (i.e. ScatterPlotModel or BarChartModel) and instead just returns [object of the object], so the instance with an error?

Hope this helps,

+1
source

I think I know where the "error" is: some declaration

 public model: CustomModelType 

does not work;

But, if you create a collection like this:

  new MyCustomCollection(null, { model: CustomModelType }); 

Then the base station will be able to create models as expected.

Why this happens, I do not know :( It may be a mistake in determining the type.

0
source

All Articles