flow icon indicating copy to clipboard operation
flow copied to clipboard

Array of mixed object types

Open JuliaSklyar opened this issue 8 years ago • 5 comments

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

JuliaSklyar avatar Jul 12 '17 14:07 JuliaSklyar

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

JuliaSklyar avatar Jul 12 '17 14:07 JuliaSklyar

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

TrySound avatar Jul 12 '17 15:07 TrySound

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

karolinkas avatar Jun 26 '18 07:06 karolinkas

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?

chrisjcodes avatar Jul 31 '18 21:07 chrisjcodes

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?

You can check https://flow.org/en/docs/types/intersections/ just use the & instead |.

savazhelev avatar Jul 07 '22 14:07 savazhelev