I have an enum like this:
const Filter = {
ALL: 'ALL',
COMPLETED: 'COMPLETED',
UNCOMPLETED: 'UNCOMPLETED'
};
What I'd like to do is declare a union type like this:
type FilterType = Filter.ALL | Filter.COMPLETED | Filter.UNCOMPLETED
However, this fails, but I'm not sure why. According to the Flow docs:
When you create an object with its properties, you create a sealed object type in Flow. These sealed objects will know all of the properties you declared them with and the types of their values.
So, if I'm reading that correctly, Flow should be able to create a type from those values. Instead, it fails with:
Cannot use string as a type because string is a value. To get the type of a value use typeof.
Here's a link to a Flow Try with a possible solution (that I'm not happy with) and other approaches that have unsuccessfully worked.
There's an easier solution. You can use $Values
utility to get union of value types. And in order to make flow resolve types as literal types instead of just string
the object should be frozen:
const FilterA = Object.freeze({
ALL: 'ALL',
COMPLETED: 'COMPLETED',
UNCOMPLETED: 'UNCOMPLETED'
});
type FilterTypeA = $Values<typeof FilterA>;
let a: FilterTypeA = FilterA.ALL; //OK
a = 'COMPLETED'; //OK
a = 'foo'; //$Expect error: string is incompatible with enum FilterTypeA
Try
This pattern works since 0.60.0 version
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With