【发布时间】:2017-12-03 02:58:25
【问题描述】:
有没有办法在流中正确调整输入参数的返回类型?
以下函数是一个简单的可选递归,对于流解析来说应该不会太难,但我无法让它工作:
type XYpos = {| x: number, y: number |}
type RelativeCoordinates = {...XYpos} | Array<{...XYpos}>; // Use spread to loose the exact type
type MappedCoordInput = XYpos | Array<XYpos>;
function getMappedCoords(position: RelativeCoordinates,
width: number,
height: number): MappedCoordInput {
if (position instanceof Array) {
return position.map(p => getMappedCoords(p, width, height));
}
return {
x: position.x * width,
y: position.y * height,
};
}
这给出了 Flow 中的错误(here 是“Flow try”):
6: return position.map(p => getMappedCoords(p, width, height));
^ array type. Has some incompatible type argument with
3: type MappedCoordInput = XYpos | Array<XYpos>;
^ array type
Type argument `T` is incompatible:
6: return position.map(p => getMappedCoords(p, width, height));
^ array type. Inexact type is incompatible with exact type
3: type MappedCoordInput = XYpos | Array<XYpos>;
^ object type
我也玩过泛型,但这似乎没有帮助:
type XYpos = {| x: number, y: number |}
type CoordInput = XYpos | Array<XYpos>;
function getMappedCoords<P: CoordInput>(position: P,
width: number,
height: number): CoordInput {
if (position instanceof Array) {
return position.map(p => getMappedCoords(p, width, height));
}
return {
x: position.x * width,
y: position.y * height,
};
}
更新
强制转换解决了直接错误,但没有解决有关通过输入参数解析返回类型的问题:
type XYpos = {| x: number, y: number |}
type RelativeCoordinates = {...XYpos} | Array<{...XYpos}>;
type MappedCoordinates = XYpos | Array<XYpos>;
function getMappedCoords(
position: RelativeCoordinates,
width: number,
height: number,
): MappedCoordinates {
if (position instanceof Array) {
const ret = position.map(p => getMappedCoords(p, width, height));
return ((ret: any): Array<XYpos>);
}
const truePos: XYpos = {
x: position.x * width,
y: position.y * height,
};
return truePos;
}
const pos: XYpos = getMappedCoords({ x: 1, y: 1}, 2, 2);
const arrayXpos: Array<XYpos> = getMappedCoords([{x: 1, y: 1}], 2, 2);
Flow测试平台依旧complains:
22: const pos: XYpos = getMappedCoords({ x: 1, y: 1}, 2, 2);
^ array type. Inexact type is incompatible with exact type
22: const pos: XYpos = getMappedCoords({ x: 1, y: 1}, 2, 2);
^ object type
23: const arrayXpos: Array<XYpos> = getMappedCoords([{x: 1, y: 1}], 2, 2);
^ object type. This type is incompatible with
23: const arrayXpos: Array<XYpos> = getMappedCoords([{x: 1, y: 1}], 2, 2);
^ array type
【问题讨论】:
-
为什么不简单地使用两个不同的函数?!
-
@JonasW。是的 - 这就是我所说的廉价后备解决方案:-D
-
打字的感觉是为了让你的代码安全。这些多型男根本找不到错误,所以很没意思……
-
@JonasW。我同意这种编码风格有好处,但问题不在于编码风格。有很多库有类似的问题,除非我们想重写所有库,否则如果 Flow 允许更大的灵活性以便可以通过适当的 Flow 类型扩展这些库,那就太好了。
-
为什么还要输入它们呢?
标签: javascript flowtype