如果将检查放入变量中,为什么流程会抱怨?

时间:2019-05-13 14:58:38

标签: javascript reactjs flowtype

我想使用一个变量来验证数组。所以我这样做了:

const length = array ? array.length : 0;

if (length) {
   array.map(_ => _.displayName);
}

为此,我遇到了流错误:Cannot call 'array.map' because property地图is missing in undefined [1].Flow(InferError)

1 个答案:

答案 0 :(得分:0)

在不知道array类型的情况下很难说出您要做什么。

  

如果将检查放入变量中,为什么流程会抱怨?

作为一般规则,这无法顺畅进行。流的细化非常有限。 documentation on refinement基本上列出了受支持的每种优化形式,而检查length不是其中之一。您无法真正做到将某物是某种类型的事实带到后来。看,例如:

// Let's assume `array` is `Array<any> | null` for the sake of this example
const array: Array<any> | null = ([]: any);

我们可以通过以下操作将array精炼为一个数组:

if (Array.isArray(array)) {
  // here, _within this block,_ `array` is of type `Array<any>`
  (array: Array<any>);
}

// Here, `array` is `Array<any> | null` again
(array: Array<any>); // Error! Cannot cast `array` to array type 
  // because null [1] is incompatible with array type [2].

我们也可以做相反的事情:

if (array === null) {
  // here, array is `null`
  (array: null);
} else {
  // and because this is in an `else` block, flow knows that
  // array is `Array<any>` here
  (array: Array<any>);
}

// ...and now it's back to `Array<any> | null` again:
(array: null); // Error! Cannot cast...

因为我们的工会只有两种选择,一个真实的选择 还有一个假的,我们可以检查array的真实性 完善它:

if (array) {
  (array: Array<any>);
} else {
  (array: null);
}

那我们不能做的事情呢?

流程不够聪明,无法理解arrayIsArray 包含有关精炼array的信息:

const arrayIsArray = Array.isArray(array);
if (arrayIsArray) {
  (array: Array<any>); // Error! Cannot cast...
}

一般而言,优化范围仅限于 声明它们出现在其中。

Try Flow