Reputation: 44589
I apologize in advance for the vague title, but I had issue to succinctly describe my issue.
I'm having a class Table
which takes a dynamic Row
class with which it'll wrap the rows returned from a class method getRow()
. My issue is that I cannot get it to work in flow without loosing the type returned from getRow()
.
Here's what I have so far:
// @flow
class Row {
constructor() {}
};
class RowA extends Row {};
class RowB extends Row {};
class Table<RowType: Class<*>> {
Row: RowType;
constructor(RowClass: RowType = Row) {
this.Row = RowClass;
}
getRow() {
return new this.Row();
}
};
const a = new Table(RowA);
(a.getRow(): RowA);
const b = new Table(RowB);
(b.getRow(): RowB);
const c = new Table();
(c.getRow(): Row);
And the error it returns:
22: (a.getRow(): RowA);
^ Cannot cast `a.getRow()` to `RowA` because `RowB` [1] is incompatible with `RowA` [2].
References:
17: return new this.Row();
^ [1]
22: (a.getRow(): RowA);
^ [2]
25: (b.getRow(): RowB);
^ Cannot cast `b.getRow()` to `RowB` because `RowA` [1] is incompatible with `RowB` [2].
References:
17: return new this.Row();
^ [1]
25: (b.getRow(): RowB);
^ [2]
Upvotes: 0
Views: 121
Reputation: 2681
You have to implement an interface with a declared constructor or you extend a class with a (predefined) constructor.
RowInterface
and class Row
are interchangeable int the template param for class Table
.
I also added types to the getRow()
method. Please see also the alternative initialization (you don't need a cast):
const a = new Table<RowA>(RowA);
let rA : RowA = a.getRow();
full code:
// @flow
interface RowInterface {
constructor():void;
}
class Row implements RowInterface {
constructor(){}
};
class RowA extends Row {
};
class RowB extends Row {
};
// bound to extend Row
//class Table<Entity: Row> {
class Table<Entity: RowInterface> {
_rowConstructor: Class<Entity>;
// take a constructor
constructor(row: Class<Entity>) {
this._rowConstructor = row;
}
// return a constructed entity
getRow(): Entity {
return new this._rowConstructor();
}
};
const a = new Table<RowA>(RowA);
let rA : RowA = a.getRow();
const b = new Table<RowB>(RowB);
(b.getRow(): RowB);
Upvotes: 1