0
votes

Imagine having two data types, both of them have an id property:

type Foo = {
  id: string,
  // other props
}

type Bar = {
  id: number,
  // other props
}

Now imagine a Table component in React which accepts an array of data as a property. This component needs to be generic, but we know that it requires an id prop for every data object in the data array. This id can either be a number or a string. The props might be typed as follows:

type Props = {
  data: Array<{id: number | string}>
}

The problem is that the above notation does not work. Is there a way to be able to 'retype' certain properties?

I have looked into generic types but I can't seem to find a solution without changing the Foo and Bar type definitions.

1
Can you recreate this error on Flow Try - Harsh Vardhan
Are you just looking for a union type U = Foo | Bar and then Array<U>? - user6445533

1 Answers

0
votes

This is a bit too tricky for Flow to figure out I think. So instead of declaring a single property that both your types share, you can declare your array as containing types Foo | Bar.

This is nice because it has even less repetition than your original code, and in each branch of that if statement you have free access to other unique properties of Foo or Bar without any issues.

// @flow

type Foo = {
  id: string,
  // other props
}

type Bar = {
  id: number,
  // other props
}

type Props = {
  data: Array<Foo | Bar>
}

const foo: Foo = { id: 'A' }
const bar: Bar = { id: 1 }
const props: Props = { data: [foo, bar] }

for (const item of props.data) {
  if (typeof item.id === 'string') {
    console.log('I am a Foo')
  } else {
    console.log('I am a Bar')
  }
}

Try Flow Link