Flow抱怨减少返回单个布尔值

时间:2016-08-04 23:05:06

标签: javascript flowtype

我不确定我在这里做错了什么:

export function subscriptionsReady(handles: Array<Object>): boolean {
  if (handles.length === 1) return handles[0].ready();

  return handles.reduce((a: any, b: Object): boolean => {
    return (typeof a === 'object' ? a.ready() : a) && b.ready();
  });
}

流量错误:

  9:   return handles.reduce((a: any, b: Object): boolean => {
              ^ call of method `reduce`
  9:   return handles.reduce((a: any, b: Object): boolean => {
              ^ undefined (too few arguments, expected default/rest parameters). This type is incompatible with the expected return type of
  6: export function subscriptionsReady(handles: Array<Object>): boolean {
                                                                 ^^^^^^^ boolean

2 个答案:

答案 0 :(得分:2)

查看https://github.com/facebook/flow/blob/master/lib/core.js#L204(声明了Array#reduce的重载签名):

当您省略reduce的第二个参数时,reduce调用(以及传递给它的闭包)的返回类型必须与元素类型Object匹配。由于您将其设为boolean,因此您必须传入类型为boolean的初始值。

您的代码依赖于动态检查来区分这两种情况,但这对于Flow来说太聪明了。

答案 1 :(得分:2)

这是因为Array.prototype.reduce的{​​{3}}期望“memo”或返回的布尔值将第二个参数与.reduce()匹配。

但是,您似乎确实在尝试检查句柄中的每个对象是.ready(),在这种情况下,这可能对您更好:

function subscriptionsReady(handles: Array<Object>): boolean {
  return handles.every((handle): boolean => {
    return handle.ready();
  });
}

因为Array.prototype.every已经很好地输入了,所以你实际上可以省略大多数这些类型:

function subscriptionsReady(handles: Array<Object>) {
  return handles.every(handle => handle.ready());
}

Flow将能够推断出一切。

此外,您可能希望为句柄添加基本类型而不是object,如下所示:

type Handle = { ready(): boolean };

function subscriptionsReady(handles: Array<Handle>) {
  return handles.every(handle => handle.ready());
}

这将改善您滥用api时由Flow生成的错误。

通常,您应尝试定义这些类型,而不是使用Object