Does Typescript support the ?. operator? (And, what's it called?)
Update: it is supported as of TypeScript 3.7 and called Optional chaining: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining
I can't find any reference to it whatsoever in the TypeScript language specification.
As far as what to call this operator in CoffeeScript, it's called the existential operator (specifically, the "accessor variant" of the existential operator).
From CoffeeScript's documentation on Operators:
The accessor variant of the existential operator
?.
can be used to soak up null references in a chain of properties. Use it instead of the dot accessor.
in cases where the base value may be null or undefined.
So, the accessor variant of the existential operator appears to be the proper way to refer to this operator; and TypeScript does not currently appear to support it (although others have expressed a desire for this functionality).
Not as nice as a single ?, but it works:
var thing = foo && foo.bar || null;
You can use as many && as you like:
var thing = foo && foo.bar && foo.bar.check && foo.bar.check.x || null;
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'));