Reputation: 123
I have a Flow type defined as
export type fruit = 'apple' | 'orange' | 'pear';
What I want to do is validate a string and see if it matches any of the values defined in this type.
Is there a way to do this?
Upvotes: 3
Views: 260
Reputation: 18922
This is definitely kind of clunky, build you could also do:
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);
Upvotes: 0
Reputation: 1335
If you are talking about type refinement from a string into one of these values, there's not currently an elegant way of doing this.
A very similar issue was posted here a few days ago here and an issue raised here.
To do this with flow and not get errors you need to manually type out the combinations using either an if statement or switch statement,
// @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;
}
}
Upvotes: 0
Reputation: 14208
The best approach is to use an array
then validate by using Array#includes
like this.
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"));
Upvotes: 1