Как проверить, существует ли значение внутри типа потока javascript

#javascript #ecmascript-6 #types #flowtype

Вопрос:

У меня есть тип потока, определенный как

 export type fruit = 'apple' | 'orange' | 'pear';
 

Что я хочу сделать, так это проверить строку и посмотреть, соответствует ли она какому-либо из значений, определенных в этом типе.

Есть ли способ сделать это?

Ответ №1:

Лучший подход-использовать, а array затем проверить, используя Array#includes вот так.

 const fruits = ['apple', 'orange', 'pear'];
const isValid = anyFruit => fruits.includes(anyFruit);

console.log(isValid("apple"));
console.log(isValid("orange"));
console.log(isValid("pear"));
console.log(isValid("banana")); 

Комментарии:

1. Это ответ на ваш вопрос? Дайте мне знать, если вам понадобится какая-либо помощь ^^! @Дэн Петтис

Ответ №2:

Если вы говорите об уточнении типа из строки в одно из этих значений, в настоящее время нет элегантного способа сделать это.

Очень похожая проблема была опубликована здесь несколько дней назад, и здесь был поднят вопрос.

Чтобы сделать это с потоком и не получить ошибок, вам нужно вручную ввести комбинации, используя оператор if или оператор switch,

пробовать

 // @flow
type fruit = 'apple' | 'orange' | 'pear';

const func = (f: string): fruit | void => {
  const fruits = ['apple', 'orange', 'pear'];
  if (fruits.includes(f)) {
    return f; // This one errors out because you cannot type refine using
  }
}

const func2 = (f: string): fruit | void => {
  if (f === 'apple' || f === 'orange' || f === 'pear') {
    return f;
  }
}

const func3 = (f: string): fruit | void => {
  switch (f) {
    case 'apple':
    case 'orange':
    case 'pear':
      return f;
  }
}

 

Ответ №3:

Это определенно довольно неуклюжая сборка, которую вы также могли бы сделать:

 type FruitMap = {
  apple: '',
  pear: '',
}

const FRUIT_MAP: FruitMap = Object.freeze({
  apple: '',
  pear: '',
});

type Fruit = $Keys<FruitMap>;

const apple = 'apple';
const isFruit = Object.keys(FRUIT_MAP).includes(apple);