JavaScript Optional chaining array work as a short-circuit and returns undefined if accessing the array results was null or undefined, your code won't break.
The optional chaining operator ( ?. ) enables you to read the value of a property located deep within a chain of connected objects without having to check that each reference in the chain is valid.
Optional chaining is currently not supported in Node. js version 13 and below. It will be supported from Node. js version 14 and most of the browsers as it is moved to Stage 4.
You need to put a .
after the ?
to use optional chaining:
myArray.filter(x => x.testKey === myTestKey)?.[0]
Playground link
Using just the ?
alone makes the compiler think you're trying to use the conditional operator (and then it throws an error since it doesn't see a :
later)
Optional chaining isn't just a TypeScript thing - it is a finished proposal in plain JavaScript too.
It can be used with bracket notation like above, but it can also be used with dot notation property access:
const obj = {
prop2: {
nested2: 'val2'
}
};
console.log(
obj.prop1?.nested1,
obj.prop2?.nested2
);
And with function calls:
const obj = {
fn2: () => console.log('fn2 running')
};
obj.fn1?.();
obj.fn2?.();
Just found it after a little searching on the what's new page on official documentation
The right way to do it with array is to add .
after ?
so it'll be like
myArray.filter(x => x.testKey === myTestKey)?.[0]
I'll like to throw some more light on what exactly happens with my above question case.
myArray.filter(x => x.testKey === myTestKey)?[0]
Transpiles to
const result = myArray.filter(x => x.testKey === myTestKey) ? [0] : ;
Due to which it throws the error since there's something missing after : and you probably don't want your code to be transpilled to this.
Thanks to Certain Performance's answer I learned new things about typescript especially the tool https://www.typescriptlang.org/play/index.html .
ECMA 262 (2020) which I am testing on Edge Chromium 84 can execute the Optional Chaining operator without TypeScript transpiler:
// All result are undefined
const a = {};
console.log(a?.b);
console.log(a?.["b-foo-1"]);
console.log(a?.b?.());
// Note that the following statements throw exceptions:
a?.(); // TypeError: a is not a function
a?.b(); // TypeError: a?.b is not a function
CanIUse: Chrome 80+, Firefox 74+
Well, even though we figured out the correct syntax, the code doesn't make much sense to me.
The optional chaining in the code above is making sure, that the result of myArray.filter(x => x.testKey === myTestKey)
is not null
and not undefined
(you can have a look at the TS output). But it is not possible anyway, because the result of the filter
method is always an array
. Since JavaScript doesn't throw "Array bounds exceeded", you are always safe when you try to access any index - you will get undefined
if this element doesn't exist.
More example to make it clear:
const myArray: string[] = undefined
console.log(myArray.filter(x => x)?.[0]) //throws Cannot read property 'filter' of undefined
//in this example the optional chaining protects us from undefined array
const myArray: string[] = undefined
console.log(myArray?.filter(x => x)[0]) //outputs "undefined"
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