Flowtype-строка, несовместимая со строковым перечислением


У меня есть значение, которое приходит из select input и имеет тип string, однако я хочу передать его в функцию (updateLanguage), которая получает в качестве аргумента строковое перечисление с псевдонимом типа ( Language).

Проблема, с которой я сталкиваюсь, заключается в том, что Flow позволяет мне вызыватьupdateLanguage , Если я явно сравниваю свое строковое значение со строками перечисления и хочу использовать функцию array, такую как array.включает в себя.

Это кодовое упрощение моего Задача:

// @flow

type SelectOption = {
    value: string
};
const selectedOption: SelectOption = {value: 'en'};

type Language = 'en' | 'pt' | 'es';
const availableLanguages: Language[] = ['en', 'pt'];

function updateLanguage(lang: Language) {
    // do nothing
}

// OK
if(selectedOption.value === 'en' || selectedOption.value === 'pt') {
  updateLanguage(selectedOption.value);
}

// FLOWTYPE ERRORS
if(availableLanguages.includes(selectedOption.value)) {
  updateLanguage(selectedOption.value);
}

Текущий поток v0. 30. 0 дает следующий результат:

example.js:21
 21: if(availableLanguages.includes(selectedOption.value)) {
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `includes`
 21: if(availableLanguages.includes(selectedOption.value)) {
                                    ^^^^^^^^^^^^^^^^^^^^ string. This type is incompatible with
  9: const availableLanguages: Language[] = ['en', 'pt'];
                               ^^^^^^^^ string enum

example.js:22
 22:   updateLanguage(selectedOption.value);
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call
 22:   updateLanguage(selectedOption.value);
                      ^^^^^^^^^^^^^^^^^^^^ string. This type is incompatible with
 11: function updateLanguage(lang: Language) {
                                   ^^^^^^^^ string enum


Found 2 errors

Как я могу проверить, что строковое значение является частью перечисления масштабируемым образом?

1 10

1 ответ:

Вот масштабируемое и безопасное решение:

const languages = {
  en: 'en',
  pt: 'pt',
  es: 'es'
};

type Language = $Keys<typeof languages>;

const languageMap: { [key: string]: ?Language } = languages;

function updateLanguage(lang: Language) {
    // do nothing
}

type SelectOption = {
    value: string
};
const selectedOption: SelectOption = {value: 'en'};

if(languageMap[selectedOption.value]) {
  updateLanguage(languageMap[selectedOption.value]);
}