This is defined in the ECMAScript Optional Chaining specification, so we should probably refer to optional chaining when we discuss this. Likely implementation:
const result = a?.b?.c;
The long and short of this one is that the TypeScript team are waiting for the ECMAScript specification to get tightened up, so their implementation can be non-breaking in the future. If they implemented something now, it would end up needing major changes if ECMAScript redefine their specification.
See Optional Chaining Specification
Where something is never going to be standard JavaScript, the TypeScript team can implement as they see fit, but for future ECMAScript additions, they want to preserve semantics even if they give early access, as they have for so many other features.
Short Cuts
So all of JavaScripts funky operators are available, including the type conversions such as...
var n: number = +myString; // convert to number
var b: bool = !!myString; // convert to bool
Manual Solution
But back to the question. I have an obtuse example of how you can do a similar thing in JavaScript (and therefore TypeScript) although I'm definitely not suggesting it is a graceful as the feature you are really after.
(foo||{}).bar;
So if foo
is undefined
the result is undefined
and if foo
is defined and has a property named bar
that has a value, the result is that value.
I put an example on JSFiddle.
This looks quite sketchy for longer examples.
var postCode = ((person||{}).address||{}).postcode;
Chain Function
If you are desperate for a shorter version while the specification is still up in the air, I use this method in some cases. It evaluates the expression and returns a default if the chain can't be satisfied or ends up null/undefined (note the !=
is important here, we don't want to use !==
as we want a bit of positive juggling here).
function chain<T>(exp: () => T, d: T) {
try {
let val = exp();
if (val != null) {
return val;
}
} catch { }
return d;
}
let obj1: { a?: { b?: string }} = {
a: {
b: 'c'
}
};
// 'c'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = {
a: {}
};
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = {};
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = null;
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
property ?? property2
, but if you triedproperty.company ?? property1.company
andproperty
was null, you'd get aNullReferenceException
– mattytommov3.7
and it's calledOptional Chaining
. See my answer for code examples. – zoran404