Поток: как отфильтровать тип из набора типов объединения - PullRequest
0 голосов
/ 29 мая 2020

Я пытаюсь отфильтровать определенный c тип объекта из списка типов объединения. Вот моя попытка до сих пор.

/* @flow */

type Human = {|
  name: string
|};

type Droid = {|
  model: string
|};

type LivingThings = {
   things: [Human | Droid]
}

const getHumans = (livingThings: LivingThings): Human[] => {
    return livingThings.things.filter((thing) => {
       return 'name' in thing;
    })
}

Однако это жалуется на ошибку по этой ссылке: Link

return livingThings.things.filter ( (вещь) => {^ Невозможно вернуть livingThings.things.filter(...), потому что свойство model отсутствует в Human 1 , но существует в Droid [2] в arr

1 Ответ

0 голосов
/ 03 июня 2020

К сожалению, Flow не уточняет типы с помощью фильтра . Связанная проблема довольно старая, и она уже давно присутствует в дорожной карте. Как было предложено выше, вы можете привести к любому или использовать $ExpectError для создания локально небезопасной функции. В качестве альтернативы вы можете использовать императивный подход l oop:

const res: Human[] = [];
for (thing of livingThings.things) {
  if (typeof thing.name === 'string') {
    res.push(thing)
  }
}
return res;

Или создать полезную вспомогательную функцию mapMaybe, которую вы можете повторно использовать во многих других случаях:

function mapMaybe<A, B>(f: A => ?B, xs: A[]): B[] {
  // $ExpectError or alternatively write loop here
  return xs.map(f).filter(notUndefinedOrNull);
}

mapMaybe(thing => {
  if (typeof thing.name === 'string') {
    return thing;
  }
  return null;
}, livingThings.things);
...