Flow questions seem to garner few answers, but here goes:
type Base = {
foo: string,
bar: string
}
type Derived1 = Base & {
conditional: false
}
type Derived2 = Base & {
conditional: true,
baz: string
}
type One = {
foo: string,
bar: string,
conditional: boolean
}
type Two = One & {
baz: string
}
type Return1 = Derived1 | Derived2 // fails
type Return2 = One | Two // works, but not desired
function test(conditional: boolean): Return1 {
return {
foo: "foo",
bar: "bar",
conditional,
...conditional ? {baz: "baz"} : {}
}
}
It is preferable for the return value of test
to be one of the Derived*
types (Return1
rather than Return2
), where the conditional
property is a boolean literal.
The intention is for flow to understand that if conditional
is true
, then the object test
returns must contain baz
and vice versa.
Is this not possible?
Flow isn't quite smart enough to figure it out for you. You have to do something like:
function test(conditional: boolean): Return1 {
const base = {
foo: "foo",
bar: "bar",
}
if (!conditional) {
return Object.assign({}, base, { conditional });
} else {
const result: Derived2 = Object.assign({}, base, { conditional }, {baz: "baz"});
return result;
}
}
More info here: https://flow.org/blog/2016/07/01/New-Unions-Intersections/
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments