This is a follow up question I asked incidentally at the end of Why does the TypeScript compiler compile its optional chaining and null-coalescing operators with two checks? As resident TypeScript legend jcalz pointed out in a comment, it does deserve its own question.
// Why does the JavaScript treat
x?.y
// as
x === null || x === void 0 ? void 0 : x.y
// instead of
x === null || x === void 0 ? x : x.y
// ?
When x == null
, the latter would preserve null
while the former always returns undefined
.
Modern browsers support ?.
natively, so we can test this behavior.
const test = () => {
console.log('undefined?.x\t\t==>\t', undefined?.x);
console.log('null?.x\t\t\t==>\t', null?.x);
console.log('null?.x === null\t==>\t', null?.x === null);
};
try {
eval('null?.x');
test();
} catch {
console.error('Your browser does not support optional chaining syntax.');
console.info('While optional chaining is supported by all modern browsers, this will not work in browsers that do not support the syntax.')
console.warn('😮');
console.info('Shocking, I know.');
console.info('Compatibility chart: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining#browser_compatibility');
}
null?.x
isundefined
and notnull
. So are you asking why TS decided to implement downleveling so that it produces JS-spec compliant code? (Answer: it makes kittens sad when TS downlevels improperly 😿) Or are you asking why JS decided to make optional chaining short-circuit toundefined
instead of preserving the particular flavor of nullishness passed in? (Answer: not sure yet) – Charettenull?.x
isundefined
because thex
property ofnull
would beundefined
, notnull
if you could dereferencenull
like any other thing that lacks anx
property. – Charette