An alternative to optional chaining is to make something like this:
const optionalChaining = (obj: Object, ...props: string[]) =>
props.reduce((o: any, prop: string) => (o || {})[prop] , obj);
That is:
- Try to access the
prop
in every iteration, even if it returns undefined
- In case the previous iteration returned
undefined
, just create an object on the fly to not throw an Error because you're trying to access props of undefined.
See how Array.prototype.reduce() works, but I like to think that you can use when you want transform an array in one value.
In this case, you want to get an array of props, and get the "chained value" of them or undefined
if there's not a valid prop among them.
You could use it like:
const optionalChaining = (obj: Object, ...props: string[]) =>
props.reduce((o: any, prop: string) => (o || {})[prop] , obj);
const foo = {
data: {
InstanceStatuses: [
{ InstanceId: 'bar' }
]
}
};
console.log(
optionalChaining(
foo,
'data',
'InstanceStatuses',
'0',
'InstanceId'
)
);
console.log(
optionalChaining(
foo,
'data',
'InstanceStatuses',
'1',
'InstanceId'
)
);
The advantage is that Array.prototype.reduce
has a good browser compatibility, in other words, is a better cross-browser solution, but I would prefer optional chaining syntax when it will has a good major browsers support.
By other hand, maybe Babel could be useful if browser compatibility matters for you.