HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
tc39
proposal-optional-chaining
HTML2017–2022
tc39 / proposal-optional-chaining · Archived

proposal-optional-chaining

Discover this repository through its Hacker News conversations.

19Distinct people
19Mentions
0Explicit recommenders
4.9KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

A public description has not been verified.

Where it is used

No documented product use was verified in the last source check.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 1:49:46 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year19 dated mentions

Observed mentions: 2017-06-27 12:43:48 UTC to 2022-08-03 04:43:56 UTC.

02462017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 4 mentions; 1 submissions, 3 comments20172018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 7 mentions; 0 submissions, 7 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 6 mentions; 1 submissions, 5 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2022

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC413
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC707
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC615
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC101
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC000
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC101

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
Optional Chaining for JavaScript Status ECMAScript proposal at stage 4 of the process. Authors Claude Pache (github) Gabriel Isenberg (github, twitter) Daniel Rosenwasser (github, twitter) Dustin Savery (github, twitter) Overview and motivation When looking for a property value that's deep in a tree-like structure, one often has to check whether intermediate nodes exist: var street = user.address && user.address.street; Also, many API return either an object or null/undefined, and one may want to extract a property from the result only when it is not null: var fooInput = myForm.querySelector('input[name=foo]') var fooValue = fooInput ? fooInput.value : undefined The Optional Chaining Operator allows a developer to handle many of those cases without repeating themselves and/or assigning intermediate results in temporary variables: var street = user.address?.street var fooValue = myForm.querySelector('input[name=foo]')?.value When some other value than undefined is desired for the missing case, this can usually be handled with the Nullish coalescing operator: // falls back to a default value when response.settings is missing or nullish // (response.settings == null) or when response.settings.animationDuration is missing // or nullish (response.settings.animationDuration == null) const animationDuration = response.settings?.animationDuration ?? 300; The call variant of Optional Chaining is useful for dealing with interfaces that have optional methods: iterator.return?.() // manually close an iterator or with methods not universally implemented: if (myForm.checkValidity?.() === false) { // skip the test in older web browsers // form validation fails return; } Prior Art Unless otherwise noted, in the following languages, the syntax consists of a question mark prepending the operator, (a?.b, a?.b(), a?[b] or a?(b) when applicable). The following languages implement the operator with the same general semantics as this proposal (i.e., 1) guarding against a null base value, and 2) short-circuiting application to the whole chain): C#: Null-conditional operator — null-conditional member access or index, in read access. Swift: Optional Chaining — optional property, method, or subscript call, in read and write access. CoffeeScript: Existential operator — existential operator variant for property accessor, function call, object construction (new a?()). Also applies to assignment and deletion. The following languages have a similar feature, but do not short-circuit the whole chain when it is longer than one element. This is justified by the fact that, in those languages, methods or properties might be legitimately used on null (e.g., null.toString() == "null" in Dart): Kotlin: Safe calls — optional property access for read; optional property assignment for write. Dart: Conditional member access — optional property access. Ruby: Safe navigation operator — Spelled as: a&.b The following languages have a similar feature. We haven’t checked whether they have significant differences in semantics with this proposal: Groovy: Safe navigation operator Angular: Safe navigation operator (link to archived documentation for Angular v10) Syntax The Optional Chaining operator is spelled ?.. It may appear in three positions: obj?.prop // optional static property access obj?.[expr] // optional dynamic property access func?.(...args) // optional function or method call Notes In order to allow foo?.3:0 to be parsed as foo ? .3 : 0 (as required for backward compatibility), a simple lookahead is added at the level of the lexical grammar, so that the sequence of characters ?. is not interpreted as a single token in that situation (the ?. token must not be immediately followed by a decimal digit). Semantics Base case If the operand at the left-hand side of the ?. operator evaluates to undefined or null, the expression evaluates to undefined. Otherwise the targeted property access, method or function call is triggered normally. Here are basic examples, each one followed by its desugaring. (The desugaring is not exact in the sense that the LHS should be evaluated only once and that document.all should behave as an object.) a?.b         // undefined if `a` is null/undefined, `a.b` otherwise. a == null ? undefined : a.b a?.[x]       // undefined if `a` is null/undefined, `a[x]` otherwise. a == null ? undefined : a[x] a?.b()       // undefined if `a` is null/undefined a == null ? undefined : a.b() // throws a TypeError if `a.b` is not a function                             // otherwise, evaluates to `a.b()` a?.()       // undefined if `a` is null/undefined a == null ? undefined : a() // throws a TypeError if `a` is neither null/undefined, nor a function             // invokes the function `a` otherwise Short-circuiting If the expression on the LHS of ?. evaluates to null/undefined, the RHS is not evaluated. This concept is called short-circuiting. a?.[++x]         // `x` is incremented if and only if `a` is not null/undefined a == null ? undefined : a[++x] Long short-circuiting In fact, short-circuiting, when triggered, skips not only the current property access, method or function call, but also the whole chain of property accesses, method or function calls directly following the Optional Chaining operator. a?.b.c(++x).d  // if `a` is null/undefined, evaluates to undefined. Variable `x` is not incremented.               // otherwise, evaluates to `a.b.c(++x).d`. a == null ? undefined : a.b.c(++x).d Note that the check for nullity is made on a only. If, for example, a is not null, but a.b is null, a TypeError will be thrown when attempting to access the property "c" of a.b. This feature is implemented by, e.g., C# and CoffeeScript; see Prior Art. Stacking Let’s call Optional Chain an Optional Chaining operator followed by a chain of property accesses, method or function calls. An Optional Chain may be followed b
Read the full README on GitHub

What Hacker News says

19 sources
For comparison, here are the Javascript RFCs for the equivalent operators: https://github.com/TC39/proposal-optional-chaining https://github.com/tc39/proposal-nullish-coalescing IMO optional chaining is a lifesaver when dealing with deeply nested JSON, and it's become indispensable in our Typescript code. But we also deal with JSON from various third-party endpoints in Python, and far too often we resort to an inefficient deep_get utility to make our code sensical. > if json?.get("foo")?.get("bar")?[0]?.get("baz") may seem messy but would be infinitely better than the fragile (note the nested list-of-a-single-dict, and how bugs can appear if it's not there): > if json.get("foo", {}).get("bar", [{}])[0].get("baz") or the inefficient > if deep_get(json, "foo.bar.0.baz") It's not nearly as good as the Typescript json.foo?.bar?.[0]?.baz - but
Read the rest
it's good enough!
In PEP 505 – None-aware operators (2015)
This may feel a bit nit-picky, but they haven't been added to ECMAScript yet. There are two features here: the optional chaining operator[1] and nullish coalescing operator[2]. Both are at stage 3 of the standardization process. Changes to proposed features can still be made at stage 3 if critical issues come up. Otherwise, once implementors have sufficient experience with them (and tests & multiple implementations exist) the proposals will be eligible to move to stage 4, after which they'll be able to be included as part of the next ECMAScript spec. Both proposals are progressing through the process very smoothly, but I wouldn't rely on them for anything critical just yet. [1] https://github.com/tc39/proposal-optional-chaining [2] https://github.com/tc39/proposal-nullish-coalescing
In TypeScript 3.7 Beta
Yeah the iteratee shorthand stuff in lodash is massively convenient, however I'm starting to shy away from it in favor of more "obvious" approaches like your second example. Although that being said, for deep property access like you have, i still reach for lodash's `get`, or more recently i'm beginning to use the new stage-1 proposal for "optional chaining" (also known as null-conditional operator in C#) [0]. That turns your second example into: Object.values(object).map(i => i.myProperty?.mySubProperty) And honestly I might even reach for destructuring depending on the use case: Object.values(object).map(({myProperty}) => myProperty?.mySubProperty) As nice as lodash's syntax is, it can be confusing for those who don't know it, and even I need to step back sometimes when I see it used heavily somewhere and almost replay what is
Read the rest
In Javascript utility libraries to know in 2018
Wouldn't this swallow errors that you wouldn't want it to swallow? e.g. you try to access a property on a value that's null (which you think isn't null), and instead of getting an error, nothing happens. Idx[0] is a way better solution to dealing with the boilerplate of checking for null/undefined that has 0 runtime cost due to being compiled away by babel. It works with type systems, and you can even use it as a babel macro[1]. With it idx(props, _ => _.user.friends[0].friends) compiles to props.user == null ? props.user : props.user.friends == null ? props.user.friends : props.user.friends[0] == null ? props.user.friends[0] : props.user.friends[0].friends Optional chaining[2] would add this to JS at the language level by using ?. as the operator. [0]: https://github.com/facebookincubator/idx [1]: https://github.com
Read the rest
In Show HN: Nothing.js – A chainable mock object which always returns itself

Showing the 15 most recent of 19 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.