I have a function foo
that takes a union of two arrays, and the only thing it does is loop over the array, but with this I get flowtype errors, that some properties are missing in the array. Is it not possible to do this? I'm not using any properties at all. They are both arrays, so flow should know that they are iterable.
A live example in the flow editor
type Handle = {|
+articleId: string,
+type: 'handle',
+accessories: Array<string>,
+positionInfo: string,
|};
type Leg = {|
+articleId: string,
+type: 'leg',
|};
type Entity = Handle | Leg;
function foo(entities: Array<Handle> | Array<Leg>) {
entities.forEach(() => {})
}
You can type the array as containing Entity
objects (e.g. Array<Entity>
), which you can later refine. Alternatively, you could type the input as Array<Handle | Leg>
, but since you already have the Entity
type defined, we should use that.
(Try)
// I made these types writeable and non-exact since it
// doesn't seem to matter for the sake of this question.
// You can make them read-only and exact in your code if
// you want (and I personally would unless I had good
// reason not to).
type Handle = {
type: 'handle',
articleId: string,
accessories: Array<string>,
positionInfo: string,
}
type Leg = {
type: 'leg',
articleId: string,
}
type Entity = Handle | Leg;
function foo(entities: Array<Entity>) {
entities.forEach(entity => {
// At this point, flow knows that our `entity` variable
// either contains a Handle or a Leg (from the above
// definition of the `Entity` type.) We can use a
// refinement to figure out which one it is:
if (entity.type === 'leg') {
const {type, articleId} = entity
console.log("A leg", type, articleId)
} else if (entity.type === 'handle') {
const {type, articleId, positionInfo} = entity
console.log("A handle", type, articleId, positionInfo)
} else {
// We can even assert that we covered all possible
// cases by asserting that the `entity` value has
// no remaining union cases and is therefore empty
(entity: empty)
}
})
}
const entitiesExample = [
{articleId: 'blah', type: 'leg'},
{articleId: 'toot', type: 'handle', accessories: [], positionInfo: 'bar'}
]
foo(entitiesExample)
Sidenote: I noticed flow had trouble refining the types if I used ==
check on the type
property instead of the above ===
. If anyone has any idea what's going on there, I'd love to know, since my intuition is that ==
should work fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With