Using booleans to spread into objects does not work correctly:
const a = false;
const b = {
...(a && {}),
};
2: const b = {
^ boolean [1] is not an object.
References:
1: const a = false;
^ [1]
No errors!
https://flow.org/try/#0MYewdgzgLgBAhjAvDAZnANhApgbgFCiSwBGSMA3njDAHR0AUCAZExQL4CUANHmzkA
Spreading false into an object does nothing, and if a was true, we would not spread a boolean, because we would move along the && to the object. So this should be permitted.
In Chrome:

Background: This pattern is used often when composing styles in CSS-in-JS libraries.
@TrySound, @danwang Why the downvotes? It took me a while, but this actually seems to be about something factual. Whatever you think about that expression, it does not result in a boolean as claimed by Flow. I would understand if Flow complains with __an__ error (Flow is opinionated after all and does not accept something just because it is possible in JS), but I don't understand the actual error.
PS: Here's the spec for object spread, in my current state I'm not capable of deciphering from this what is supposed to happen when there's a boolean instead of an object. Code generated by Babel works just fine though. I think item 1 under headline 2.3 applies (spec).
(OP) Of course, if there already is a boolean there are plenty of ways to achieve the desired outcome in other ways. Extreme brevity is not a goal when you use Flow.
@lll000111 this should probably have different message, but spreading boolean to object doesn't feel right. Though I can understand spreading null which has type object.
For reference, here's what the relevant pattern looks like:
const style = {
display: "flex",
justifyContent: "center",
alignItems: "center",
...(disabled && {
color: "#888",
cursor: "auto",
}),
};
There is some congruity with React.Node being a supertype of falsy values:
const a = false
return (
<div>
{a}
</div>
);
I believe this is the best pattern to conditionally include a key during object declaration, and I would love to see this implemented in flow.
For the people that think this isn't legal js, tc39 explicitly confirmed that it is valid.
For anyone interested in a workaround while this isn't 'fixed', I'm currently using:
Instead of:
const condition = false
const myobj = {
akey: 'a value',
...(condition && { key: 'value' }),
}
I'm going with:
const condition = false
const myobj = {
akey: 'a value',
...(condition ? { key: 'value' } : {}),
}
Even though it works with small objects, it gets funny when dealing with objects that span multiple lines, since the colon gets pushed down the code:
const condition = false
const myobj = {
akey: 'a value',
...(condition ? {
key: 'value',
color: 'red',
background: '1px solid black',
} : {}),
}
I usually avoid using long ternaries.
I also have another workaround solution too. 馃ぃ
{...Array(condition)[0] && yourObject}
Does the project no longer maintain?
@lehainam125 Do you see it's not maintained?
https://github.com/facebook/flow/commits/master
What's the status on this?
I don't think it is right to typecast false to {} like spread does.
Object.assign also disallows it
1: Object.assign({}, false) ^ boolean [1] is not an object.
References:
1: Object.assign({}, false)
^ [1]
TypeScript also doesn't support this
Most helpful comment
I believe this is the best pattern to conditionally include a key during object declaration, and I would love to see this implemented in flow.
For the people that think this isn't legal js, tc39 explicitly confirmed that it is valid.
For anyone interested in a workaround while this isn't 'fixed', I'm currently using:
Even though it works with small objects, it gets funny when dealing with objects that span multiple lines, since the colon gets pushed down the code:
I usually avoid using long ternaries.