Flow: Flow doesn't refine type when using a reference of `Array.isArray`

Created on 22 Sep 2016  路  4Comments  路  Source: facebook/flow

Example:

let isArray = Array.isArray

function f (arr: Array<mixed>): Array<mixed> {
  let subArr:mixed = []

  if (isArray(subArr)) {
    return subArr
  }

  return []
}

Flow result:

7:     return subArr
              ^ mixed. This type is incompatible with the expected return type of
3: function f (arr: Array<mixed>): Array<mixed> {
                                   ^ array type

However, it refines just fine in the following code:

function f (arr: Array<mixed>): Array<mixed> {
  let subArr:mixed = []

  if (Array.isArray(subArr)) {
    return subArr
  }

  return []
}

Most helpful comment

@HeavenVolkoff can you reopen this? Predicates are already merged, but this is still a problem. Another example of incorrect behaviour:

const Array = {
  isArray: () => true
};

function test(x: null | Array<mixed>) {
  if (Array.isArray(x)) {
     x.forEach(() => {}); 
  }
}

All 4 comments

Array.isArray is handled specially right now. If/when https://github.com/facebook/flow/issues/34 is implemented, then the isArray method could be annotated as a normal type-checking function and I assume this would be handled correctly.

Ok, I will close this issue and follow development on #34, thanks.

@HeavenVolkoff can you reopen this? Predicates are already merged, but this is still a problem. Another example of incorrect behaviour:

const Array = {
  isArray: () => true
};

function test(x: null | Array<mixed>) {
  if (Array.isArray(x)) {
     x.forEach(() => {}); 
  }
}

This problem still persists as of v0.107.0.

Was this page helpful?
0 / 5 - 0 ratings