简体   繁体   中英

Defining a Union Type from object values in Flow

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM