josemigallas
josemigallas

Reputation: 3909

How to use interface to type function argument in Flow

I'm trying to implement a React component that contains a list of options and shows their id and name. I want this component to be reusable so I define an interface Option to ensure the required fields are always provided.

And here comes the issue: if I pass any type with more fields than those 2 { id, name, /* anything */}, Flow complains. Is it not possible to use interfaces in Flow like this?

Here's the minimal relevant code:

interface Option {
  id: string,
  name: string
}

const List = (options: Option[]) => {
  options.forEach(o => null)
}

type ImplementsOption = {
  id: string,
  name: string,
  description: string
}

const plans: ImplementsOption[] = []

List(plans)

Error:

Cannot call List with plans bound to options because property description is missing in Option 1 but exists in ImplementsOption [2] in array element.

Trying with casting:

List((plans: Option[]))

And also with classes:

class ComplexOption implements Option {
  id: string
  name: string
}

const complexOptions: ComplexOption[] = []

List(complexOptions)

Nothing seems to work!

There is a playground with all these snippets already.

Upvotes: 0

Views: 211

Answers (1)

user11307804
user11307804

Reputation: 828

Imagine we had a list of ImplementsOption: [{ id: 'id', name: 'name', description: 'description' }, ...]. Now we pass it into the List function, which has the signature Option[] => void. This is totally valid from the point of view of List since ImplementOption is a supertype of Option. However, there is no guarantee in the List function that it won't modify the list that is passed in. Thus, the function could add an element of type Option to the list, which would be valid for a Option[] but invalid for a ImplementsOption[].

To fix this, you can type plans as a $ReadOnlyArray<Option>, which tells Flow that the List function will not modify the elements (try flow).

Reference issues #4425, #4483, or #5206 for more information.

Upvotes: 2

Related Questions