flowtype:如何通过参数count / types重载函数返回类型?

时间:2017-03-01 18:23:56

标签: javascript overloading flowtype

我想定义一个像

这样的重载函数
function first(n?: number) {
  if (number === undefined) {
    // returns a single Item
    return items[0];
  }

  // returns an array of Item
  return items.slice(0, n);
}

以便这些语句类型检查:

const item: Item = first(); // no args, so return type is Item
const items: Array<Item> = first(5); // number arg, so return type is Array<Item>

flow知道第一次调用first会导致n === undefined(因为如果undefinedn无效,它会抱怨)并且它理解然后它将采用if分支,所以我认为它可以推断返回类型是Item,但我尝试过的任何东西都可以让任何通过或总是失败。

任何想法是否可能?在此先感谢互联网。

2 个答案:

答案 0 :(得分:4)

我没有完整的解决方案,但我在那里得到了一段时间:

const items = [1, 2, 3];

type FirstType = ((_: void) => number) & ((n: number) => Array<number>);

const first: FirstType = (n?: number) => {
  if (n === undefined) {
    // returns a single Item
    return (items[0]: any);
  } else {
    // returns an array of Item
    return (items.slice(0, n): any);
  }
}

const a: number = first();
const b: Array<number> = first(2);

tryflow

&是一种交集类型,这意味着first必须满足这两种类型的。您可以看到first()的调用以您想要的方式进行类型检查。

不幸的是,似乎Flow目前无法对first的主体进行类型检查。请注意,我必须通过any强制转换返回值以逃避类型检查器。如果你愿意放弃函数体中的类型检查,你至少可以在调用函数的地方使用它。

答案 1 :(得分:0)

这可能不适用于您编写 OP 时当前的 Flow 版本,但是尝试使用最新版本时,我发现您甚至可以在源文件中使用 declare function 来避免 {{ 的可怕语法1}}。

((_: void) => number) & ((n: number) => Array<number>)

Try Flow link

对于类方法,我发现的唯一方法是使用丑陋的 type Item = number; const items: Array<Item> = [0, 1, 2, 3, 4]; declare function first(): Item; declare function first(n: number): Array<Item>; function first(n?: number): Item | Array<Item> { if (n === undefined) { // returns a single Item return items[0]; } // returns an array of Item return items.slice(0, n); } const item: Item = first(); // no args, so return type is Item const items2: Array<Item> = first(5); // number arg, so return type is Array<Item> 语法单独声明字段类型(是否在字段声明之前使用 & 无关紧要) :

declare

Try Flow link