Flowtype - string incompatible with string listing

I have a value that comes from select input and has a type string, however I want to pass it to a function (updateLanguage), which takes as an argument an enumeration of a string with an alias of type (Language).

The problem I am facing is that Flow only allows me to call updateLanguage if I explicitly compare my string value with enum strings and I want to use an array function like array.includes.

This is the simplification of my problem code:

// @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); } 

current thread v0.30.0 gives the following result:

 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 

How to verify that a string value is part of an enumeration in a scalable manner?

+7
javascript string enums typechecking flowtype
source share
1 answer

Here is a scalable and secure solution:

 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]); } 
+8
source share

All Articles