2016-08-08 48 views
7

Ich habe einen Wert, der aus einer Select-Eingabe stammt und vom Typ Zeichenfolge ist, aber ich möchte es in eine Funktion übergeben (UpdateLanguage), die als Argument eine Zeichenfolge Enum mit einem Typ erhält Alias ​​(Sprache).Flowtype - Zeichenfolge inkompatibel mit Zeichenfolge enum

Das Problem, das ich mit Blick auf bin ist, dass Fluss erlaubt nur mir updateLanguage zu nennen wenn ich ausdrücklich meinen String-Wert mit den ENUM-Strings vergleichen, und ich mag eine Array-Funktion wie array.includes verwenden.

Dies ist ein Code Vereinfachung meines Problems:

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

Flow v0.30.0 läuft gibt die folgende Ausgabe:

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 

Wie kann ich überprüfen, ob der String-Wert Teil des ENUM ist in einer skalierbaren Weise?

Antwort

8

Hier ist eine skalierbare und sichere Lösung:

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]); 
}