Flow: Type inference could be smarter with mixed Array types

Created on 21 Sep 2016  路  7Comments  路  Source: facebook/flow

Flow Version: 0.32.0

Consider the following example:

// @flow

function foo(arr: Array<number> | Array<string>) {

}

foo([1, 2]);

I'd expect the type inference to know that [1, 2] is an array of numbers and accept the foo([1, 2]) call, but instead I get this error:

  7: foo([1, 2]);
         ^^^^^^ array literal. Could not decide which case to select
  3: function foo(arr: Array<number> | Array<string>) {
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ union type
  Case 1 may work:
    3: function foo(arr: Array<number> | Array<string>) {
                         ^^^^^^^^^^^^^ array type
  But if it doesn't, case 2 looks promising too:
    3: function foo(arr: Array<number> | Array<string>) {
                                         ^^^^^^^^^^^^^ array type
  Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 2):
    7: foo([1, 2]);
           ^^^^^^ inferred union of array element types (alternatively, provide an annotation to summarize the array element type)

Obviously I can work around this by adding annotations, but was curious: Is this a solvable problem without annotations or is this just the nature of the complicated problem inferring mixed types?

unionintersections bug

Most helpful comment

@gokulbharathi : I tested it out on 0.73.0, and it looks like Flow can handle selecting the correct type in the union of a union and an array. But it still errors out on the union of 2+ arrays. I ended up casting the array like so:

type ThingArray = Array<number> | Array<boolean>;

type ThingObj = {
  arrayOfThings: ThingArray
};

const thingObjInstance = {
  arrayOfThings: ([1, 2, 3]: Array<number>)
};

All 7 comments

I'm running into this with React Native's Animated.Value.interpolate() outputRange key, which has a signature of (Array<number> | Array<string>).

@jkk That's where I originally saw this as well.

Looks like a bug, case 2 isn't really promising

Similar issue with a union type of an array.

type TerritoryCode = 'US' | 'FR' | 'RE' | //...

type Track = {
  territories: Array<TerritoryCode> | TerritoryCode
  //...
}

const track: Track = {
  territories: [ 'US', 'FR' ]
}

I get the following error:

test-run-v2.js:99
 99:         territories: [ 'US', 'FR' ]
                          ^^^^^^^^^^^^^^ array literal. Could not decide which case to select
122:   territories: Array<TerritoryCode> | TerritoryCode
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ union type. See: src/flow-types/input-object.js:122
  Case 1 may work:
  122:   territories: Array<TerritoryCode> | TerritoryCode
                      ^^^^^^^^^^^^^^^^^^^^ array type. See: src/flow-types/input-object.js:122
  But if it doesn't, case 2 looks promising too:
  122:   territories: Array<TerritoryCode> | TerritoryCode
                                             ^^^^^^^^^^^^^ TerritoryCode. See: src/flow-types/input-object.js:122
  Please provide additional annotation(s) to determine whether case 1 works (or consider merging it with case 2):
   99:         territories: [ 'US', 'FR' ]
                            ^^^^^^^^^^^^^^ inferred union of array element types (alternatively, provide an annotation to summarize the array element type)

Do any one have solution for @acarl005 example code, i have a similiar situation. How can we provide the type of array while initializing the array.

@gokulbharathi : I tested it out on 0.73.0, and it looks like Flow can handle selecting the correct type in the union of a union and an array. But it still errors out on the union of 2+ arrays. I ended up casting the array like so:

type ThingArray = Array<number> | Array<boolean>;

type ThingObj = {
  arrayOfThings: ThingArray
};

const thingObjInstance = {
  arrayOfThings: ([1, 2, 3]: Array<number>)
};

Explicitly annotating the array type isn't really a great workaround. 鈽癸笍 But thanks for sharing @mdsib. It appears to be the only option available.

Was this page helpful?
0 / 5 - 0 ratings