Bibs
Bibs

Reputation: 1015

How to easily pick properties of a type in Flow?

I'm relatively new to Flow and trying to wrap my head around how to type the models in my app.

Let's say I have a model named Car that is modeled like so:

type Car = {
  id: string,
  make: string,
  model: string,
  owner?: ?{ name: string }
};

Now let's say my app is going to create an object that is a car, but since it has yet to be saved, it does not have the otherwise required id property:

const newCar = {
  make: 'Honda',
  model 'Accord',
};

Is there a way to easily select multiple properties of Car to assign to newCar?

Something like:

const newCar: $Pick<Car, ['make', 'model']>;?

Or is there a more idiomatic way to do this in Flow?

Upvotes: 0

Views: 687

Answers (2)

kalley
kalley

Reputation: 18462

You can do the following:

type Car = {
  id: string,
  make: string,
  model: string,
  owner?: ?{ name: string }
};

const newCar: $Diff<Car, { id: string }> = {
  make: 'Honda',
  model: 'Accord'
}

FLOW TRY

Another approach is pretty similar (but I think the first method makes intentions clearer):

const newCar: { ...Car, id?: string } = {
  make: 'Honda',
  model: 'Accord'
}

This works pretty well when all you need is to remove the id. When you start removing more fields, this can become cumbersome.

Upvotes: 3

sphire
sphire

Reputation: 596

Using intersection types you could specify a base type and a more specific version for the saved instance.

type UnsavedCar = {
  make: string,
  model: string,
  owner?: ?{ name: string }
}

type Car = UnsavedCar & {
  id: string;
}

Which also works quite well in functions such as:

function saveCar(car: UnsavedCar): Car { /* ... */ }

Upvotes: 0

Related Questions