43

Add support for Optional Chaining by rbuckton · Pull Request #33294 · microsoft/...

 4 years ago
source link: https://github.com/microsoft/TypeScript/pull/33294
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
This PR adds support for the ECMAScript Optional Chaining proposal which is now at stage 3.Optional ExpressionsAn optional expression is an expression involving a property access, element access, or call, in which the expression is guarded against null and undefined through the use of the ?. token:a?.b // optional property accessa?.[x] // optional element accessa?.() // optional callIn these cases, when a is either null or undefined, the result of the expression becomes undefined. When this happens, any side effects to the right of the ?. operator are not evaluated.When emit down-level, the above expressions are translated into the following JavaScript:var _a, _b, _c;(_a = a) === null || _a === void 0 ? void 0 : _a.b; // optional property access 'a?.b'(_b = a) === null || _b === void 0 ? void 0 : _b[x]; // optional element access 'a?.[x]'(_c = a) === null || _c === void 0 ? void 0 : _c(); // optional call 'a?.()'Optional ChainsAn optional chain is an optional expression followed by one or more subsequent regular property access, element access, or call argument lists:a?.b.c; // property access chaina?.b[x]; // element access chaina?.b(); // call chainWhen a is either null or undefined above, the rest of the chain is also not evaluated. However, if a is any other value, the expression is evaluated as normal. In the above cases, if a.b were either null or undefined, the expression would still throw as the ?. token only guards the value of a.When emit down-level, the above expressions are translated into the following JavaScript:var _a, _b, _c;(_a = a) === null || _a === void 0 ? void 0 : _a.b.c; // property access chain 'a?.b.c'(_b = a) === null || _b === void 0 ? void 0 : _b.b[x]; // element access chain 'a?.b[x]'(_c = a) === null || _c === void 0 ? void 0 : _c.b(); // call chain `a?.b()`Optional Chaining and GenericsIn addition to supporting ?.( for an optional call, we also support supplying generic type arguments to an optional call:a?.<string>(b)Optional Chaining and the Type SystemWhen running outside of strictNullChecks, optional chaining should have no observable effect on the type system, as null and undefined in most cases are removed or widened to any.When running inside of strictNullChecks, optional chaining introduces a special internal optional marker type. The optional type is a special case of the undefined type, and is treated as undefined for most type checking operations. Whenever the type checker encounters an optional expression, the null and undefined types are removed from the type of the expression and the optional type is added in its place. In this way, an optional chain can detect whether its preceding expression's type introduced a null or undefined in any step of the chain to the right of the optional expression.For example:declare let a: { b: { c: number } | undefined } | undefined;a?.b?.c; // ok: has type `number | undefined`a?.b.c; // error: object is possibly undefined (at `a?.b`)In the first case, the expression a?.b?.c is safe to evaluate as both the a variable and the b property are guarded. In the second case, we can determine that it is not safe to evaluate the c property on a?.b as the b property is possibly undefined.Fixes #16

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK