条件流在输入参数类型上的返回类型

时间:2017-12-02 16:24:08

标签: javascript flowtype

有没有办法在流中正确调整输入参数的返回类型?

以下函数是一个简单的可选递归,对于流解析来说不应该太难,但是我无法使其工作:

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是&#34; Flow try&#34;):

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,
  };
}

更新

Casting解决了即时错误,但没有解决通过输入参数解决返回类型的问题:

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

1 个答案:

答案 0 :(得分:0)

因为,如您所定义的,当您的函数接受位置数组时,映射后该数组中每个元素的类型为MappedCoordInput。这就是说position.map可以是一个数组数组,它​​与函数的返回类型不兼容 - 它只是一个对象数组,而不是一个对象数组的数组。

由于目前已编码,[[[{x: 1, y: 1}]]]是有效输入。但是,它不会运行Array<XYPos>。它将返回Array<Array<Array<XYPos>>>,它与MappedCoordInput的返回类型不匹配。