Was updating a bit of code today that returns optional props to a React component. I discovered that even though the function sometimes returns null
, it wouldn't error when the return value was immediately unpacked.
Pedantic summary of the code:
const returnPropsOrDont = (condition) => {
if (condition) return null;
return { optionalProp: 'foo' };
}
...
render() {
const { condition } = props;
return <SomeComponent
staticProp="staticProp"
{...returnPropsOrDont(condition)}
/>
}
Upon realizing this was cool, I ran to the console and tried it out on Objects and Arrays. Alas -
> {...null} // {}
> {...undefined} // {}, which is interesting because null is an object but undefined is not
> [...null] // Uncaught TypeError: object null is not iterable
I did some light Googling and found one article which suggests that TypeScript considers it a feature to make sure optionally defined values don't haunt an unsuspecting developer. Fine, but a) I'm not using TypeScript, and b) I have no idea why JS wouldn't guard Arrays in the same way.
Since this does seem like a guard against optionally defined values, why is {...null}
fine and [...null]
not?
Normally, uses of ...x
requires x
to be iterable because the point of ...
is normally to flatten an iterable into its components. An array is a prime example of an iterable.
null
is not iterable. It has no components, so it doesn't make sense to iterate over null
. for (const e of null)
will similarly fail, since of
also requires an iterable.
However, {...x}
requires x
to be enumerable because it needs not just values, but keys along with them. An object is a prime example of an enumerable.
null
is enumerable. null
is sometime treated as an object, and this is one of those cases. Objects are enumerable because they can have properties. for (const p in null)
will similarly succeed, since in
requires an enumerable.
[…null] - here you use spear operator and it works only for iterable objects (like strings, arrays, generators or custom iterable objects), but null isn't iterable object and will recieved error. You can create your own iterable object be adding special property Symbol. iterator
{...null} - works because typeof null == 'object'
, but in real life it doesn't make sense
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With