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?
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.
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: