Flow: Array of mixed object types

Created on 12 Jul 2017  路  4Comments  路  Source: facebook/flow

Error if I try to get a property from a specific Array element.

Next code

type Content = { id: number } | { text: string };
type Post = Array<Content>;
const post: Post = [{ id: 1}, { text: 'text' }];

console.log(post[0].id);

will give this error

7: console.log(post[0].id);
                       ^ property `id`. Property not found in
4: type Post = Array<Content>;
                     ^ object type

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVAXAngBwKZgDCcAdhnmWALxgDeAlgCYBcYJArgLYBGeATgF8wAHzrkAHhlYBnDH3okA5gIDcmXAQAKcWdTABBPnwCGWADzEyFDAD41AY1K6cOqWG26aAbVpgmrAEYBABoxPElWAHIJDEiBAF01VEcSaTgYPAA6eEUAChdZLwAGeMymAEo1IA

Most helpful comment

Sorry bothering your, solved it this way:

type Content = { id: number } | { text: string };
type Post = Array<Content>;
const post: Post = [{ id: 1}, { text: 'text' }];

if (post[0].id !== undefined) {
  console.log(post[0].id);
}

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVAXAngBwKZgDCcAdhnmWALxgDeAlgCYBcYJArgLYBGeATgF8wAHzrkAHhlYBnDH3okA5gIDcmXAQAKcWdTABBPnwCGWADzEyFDAD41AY1K6cOqWG26aAbVpgmrAEYBABoxPElWAHIJDEiBAF01VHooMAAKF1kvAAZ4gDomMABCKhp2EkY8KAU8RgBKOlQwMEcSaTgYPDz4RQzXHPymOrUBVCA

All 4 comments

Sorry bothering your, solved it this way:

type Content = { id: number } | { text: string };
type Post = Array<Content>;
const post: Post = [{ id: 1}, { text: 'text' }];

if (post[0].id !== undefined) {
  console.log(post[0].id);
}

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVAXAngBwKZgDCcAdhnmWALxgDeAlgCYBcYJArgLYBGeATgF8wAHzrkAHhlYBnDH3okA5gIDcmXAQAKcWdTABBPnwCGWADzEyFDAD41AY1K6cOqWG26aAbVpgmrAEYBABoxPElWAHIJDEiBAF01VHooMAAKF1kvAAZ4gDomMABCKhp2EkY8KAU8RgBKOlQwMEcSaTgYPDz4RQzXHPymOrUBVCA

This is how it should be solved. You need to refine type.

@JuliaSklyar Thanks, this still works in 2018. :-)

I have a similar issue. I have a prop that can be 3 types of collections.

items: (FaqFields | HowToVideoFields | GuideFields)[],

I am using Array.every when using items to check that the array is one type like so

if (items.every(i => _has(i, ['question', 'answer', 'id']))){
      const mappedItems = items.map(i => ({
        label: i.question,
        content: i.answer,
        id: i.id,
      }));
}

_I have also tried hasOwnProperty in place of lodash/has and just checking the first item in the collection_

This is still throwing a flow error:

[flow] Cannot get `i.question` because property `question` is missing in `HowToVideoFields` [1]. (References: [1])
[flow] Cannot get `i.question` because property `question` is missing in `GuideFields` [1]. (References: [1])

Any ideas?

Was this page helpful?
0 / 5 - 0 ratings