Is the behavior of {...false} defined? (Conditionally setting key)
qria opened this issue ยท 4 comments
This stackoverflow answer recommends using spread operator to conditionally set a key in a object.
const animal = {species: 'cat'};
const vocalAnimal = {
...animal,
...animal.species === 'cat' && {purr: 'meow'},
...animal.species === 'dog' && {bark: 'woof'},
}
// becomes: { "species": "cat", "purr": "meow" }
But this depends on a behavior of ...false
being ignored, like ...null
or ...undefined
.
Similar code without depending on the behavior might be:
const animal = {species: 'cat'};
let vocalAnimal = {...animal};
if(animal.species === 'cat'){
vocalAnimal.purr = 'meow';
}
if(animal.species === 'dog'){
vocalAnimal.bark = 'woof';
}
So is the behavior well defined/ intended/ dependable?
Yes, it should mirror Object.assign
.
In other words, your first example must be equivalent to const vocalAnimal = Object.assign({}, animal, animal.species === 'cat' && {purr: 'meow'}, animal.species === 'dog' && {bark: 'woof'});
- and Object.assign
will treat all primitives (like undefined
) as the same as {}
- in other words, this works just fine as-is.
Yes, it should mirror Object.assign.
I know it's too late, but IMO the error throwing would be much more helpful. There's no way to opt into error throwing in {...obj.undefinedVariable}
if one didn't expect it to be undefined, however it is easy to opt out of error throwing with {...(obj.undefinedVariable || {})}
. Error throwing instead of silence would point to possible errors like typos, code load order issues, wrong variables, etc.
Why should it mirror Object.assign
? I mean, how is mirroring that more beneficial?
Well, I see that
const a = {
...(someCondition && {b: 5})
}
is convenient, but IMO not more convenient than preventing bugs ๐๐.
If object spread threw like ...iterable
does, then I'd be explicitly opting into non-errors by writing
const a = {
...(someCondition && {b: 5} || {})
}
which would be nice.
const a = { ...(someCondition && {b: 5} || {}) }
@trusktr How about the code below? I think this will also handle errors
const a = {
... someCondition ? {b: 5} : {}
}