对于这个模糊的标题,我预先表示歉意,但是我有一个问题要简洁地描述我的问题。
我有一个Table
类,它带有一个动态Row
类,它将包装从类方法getRow()
返回的行。我的问题是,如果不丢失getRow()
返回的类型,就无法使其正常运行。
这是我到目前为止的内容:
// @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);
演示位于:https://flow.org/try/#0PTAEAEDMBsHsHcBQiDG0CGBnToBKDQBvRUU0FWAO0wBcAnAVxRtjoAoBKIgX0W4G5UGbHgQBBUAFMAHjUmUAJjnzwegtFmUIAQlNnylo1YQHINIgCroARtEkAeFRYCeAB0kAuUAGFhmewBUAHxBRCRkKl5ObpKC4aQU1PRMLOwqvppRCC7uoAC8RlzEZCWgNAAWAJaYAHQq+UYZ2IIlvPGgAOaSNCqcYaVkdN0MdJSglJKqFdV1CJwtZLymqFS0oOgNE6pWtpJsKmIcgmzoNV09cxxZ8IdxiWvWm5OgO3b7OkeIbNZn3b1XRm0nxWSXIT22NjenzYKF+F3gnGuRyAA
并返回错误:
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]
最佳答案
您必须使用声明的构造函数实现接口,或者使用(预定义的)构造函数扩展类。RowInterface
和class Row
在class Table
的模板参数中可以互换。
我还向getRow()
方法添加了类型。另请参见替代初始化(您不需要强制转换):
const a = new Table<RowA>(RowA);
let rA : RowA = a.getRow();
完整代码:
// @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);