Flow: Create a flow type by extending another type
Solution 1
What you're looking for is the intersection type. According to the documentation:
An intersection type requires a value to be all of the input types.
Syntax: Intersection: < type 1 > & < type 2 > ... & < type n >
The intersection type is intended to extend an existing type and add additional type requirements to it.
type someType = {
keyOne: string,
keyTwo: string
}
type someOtherType = someType & {
keyThree: string
}
const shouldBeOk: someOtherType = {
keyOne: 'biz',
keyTwo: 'buzz',
keyThree: 'baz',
}
const shouldError: someOtherType = {
keyOne: 123,
keyTwo: 'hello',
keyThree: 'world',
}
// flow error:
16: const shouldError: someOtherType = {
^ object literal. This type is incompatible with
8: type someOtherType = someType & {
^ object type
The logical opposite of the intersection type is the union type. According to the documentation:
A union type requires for a value to be one of the input types.
Syntax: Union: < type 1 > | < type 2 > ... | < type n >
As an example. you can use the union type to create an enumerable.
type fooBarBazType = 'foo' | 'bar' | 'baz';
const shouldBeOk: fooBarBazType = 'bar';
const shouldError: fooBarBazType = 'buzz';
4: const shouldError: fooBarBazType = 'buzz';
^ string. This type is incompatible with
4: const shouldError: fooBarBazType = 'buzz';
^ string enum
Solution 2
Sorry, the accepted answer is just wrong and it's working just because you didn't use exact match.
When using exact match you'll get an error:
10: const shouldBeOk: someOtherType = {
^ Cannot assign object literal toshouldBeOk
because propertykeyOne
is missing in object type 1 but exists in object literal 2. References: 6: type someOtherType = someType & {|
^ 1 10: const shouldBeOk: someOtherType = {
^ 2
The right way to do it is to use the spread
operation:
type someOtherType = {|
...someType,
keyThree: string
|}
Jon Cursi
Updated on June 19, 2022Comments
-
Jon Cursi almost 2 years
type someType = { keyOne: string, keyTwo: string, }; type someOtherType = { keyOne: string, keyTwo: string, keyThree: string, };
Both of these types are objects that contain
keyOne
andkeyTwo
, the only difference is the latter extends the former with an additional key ofkeyThree
.Rather than writing duplicated code, is it possible to build the
someOtherType
flow type by extendingsomeType
? In my mind, ES6 object rest/spread comes to mind, but I'm not sure how to accomplish something like this in Flow.Thanks!