Repository navigation
Experimental support of Optional Chaining (at least static property access) via experimentalOptionalChaining #30167
Description
Suggestion
Add experimentalOptionalChaining property to compilerOptions which will support at least static property access – the most required and expected feature.
Use Cases
For me, in 2019 the most important part of Optional Chaining is static property access. It will greatly improve DX for GraphQL client apps and make client code more robust and clean. 🚀
Current shortcomings:
- if-check-hell 🤢
- unchecked
dottedPathsas string 💩_.get(obj, ['some.nested.field'])with lodash.getobjectPath.get(obj, 'dottedPath')with object-path (900k weekly downloads 😱)
Examples
Assume we have following GraphQL response from the server on the client side:
interface IResponse {
viewer?: {
article?: {
title?: string
}
}
}
const response: IResponse = await apolloClient.query(`query {
viewer {
article(id: 15) {
title
}
}
}`);On any level, graphql may return null, so before displaying title we must check viewer and article existence.
... with if-check-hell 🤢
if (response && response.viewer && response.viewer.article && response.viewer.article.title) {
// ... display title
}Pros: statically checked (if query changed, then we will be warned about un-existed props)
Cons: to much code
... with unchecked dottedPaths as string 💩
if (_.get(response, ['viewer.article.title'])) {
// ... display title
}Pros: quite clean code
Cons: statically UNchecked (if query changed, then we will NOT be warned about un-existed props checks)
... with Optional Chaining ❤️
if (response?.viewer?.article?.title) {
// ... display title
}Pros: very clean code & static checks
Cons: not implemented in TS, but already implemented about a year ago in Flow 0.74, Eslint, Babel.
Recap
We just have 3 levels deep query, but in most cases it's deeper.
if (response && response.viewer && response.viewer.article && response.viewer.article.title) {
if (_.get(response, ['viewer.article.title'])) {
if (response?.viewer?.article?.title) {Definitely, OptionalChaining is the winner 🥇
Suggestion: repeat once more
Just add static property access from optional chaining proposal under experimentalOptionalChaining flag. This part is stable in the proposal and it is the most required feature in 2019.
Let's keep problematic optional chaining for function calling, short-circuiting, grouping, deletion, template literals – out of the scope of this issue.
Please do not reference this issue as a duplicate for issue #16 from the 2014 year, here are 2019 and requirements changed from that time.
Search Terms
Optional Chaining, null propagation.
- Stale old issue Suggestion: "safe navigation operator", i.e. x?.y #16 (discussed in 2014-2017 years)
- TC39 optional-chaining (Stage 1, but all preparations for Stage 2 were done)
Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
If a miracle will happen 😂
If you like the fact that optional chaining was shaken off the dust from #16 and may even be implemented in the near future – send a SWAG from your company to the following address
050010, Kazakhstan, Almaty,
Kabanbay Batyra 21 apt 3,
Mobile +7707234004
Pavel Chertorogov
or just give a 👍
Activity
nodkz commentedon Mar 1, 2019
I'm prepared a simple video demo with Flow and Optional Chaining: https://youtu.be/NzlDE3cWnDc
Again: I'm telling about optional chaining for reading properties from objects.
PS. Let's keep problematic optional chaining for function calling, short-circuiting, grouping, deletion, template literals – out of the scope of this issue.
lifeart commentedon Mar 1, 2019
Why this:
Better than this?
nodkz commentedon Mar 1, 2019
Alex Kanunnikov (@lifeart) please watch the video above when I breaking response interface. Such kind of things usually love to do backenders 😜
And I want to get strongly typed code with static analysis for such kind of things, rather than old-school dot-path in a string, which not understands TypeScript.
With optional chaining, TypeScript will help to catch such changes. 👍
lifeart commentedon Mar 1, 2019
Paul Damnhorn (@nodkz) this can be statically analyzed:
nodkz commentedon Mar 1, 2019
Alex Kanunnikov (@lifeart) wow! I think that it cannot be used as a good solution 😜
In such case better to use
if-check-hell😈everdimension commentedon Mar 1, 2019
I don't think that a feature like this belongs in the language.
Voronar commentedon Mar 1, 2019
Duplicate of #16?
RyanCavanaugh commentedon Mar 1, 2019
Where did this get brigaded from?
john-dulaney commentedon Mar 1, 2019
Ryan Cavanaugh (@RyanCavanaugh) HackerNews
nodkz commentedon Mar 1, 2019
Ryan Cavanaugh (@RyanCavanaugh) from twitter https://twitter.com/nodkz/status/1101432188883603456?s=19 and GraphQL community. Need to wait while US wake up for bigger feedback ;)
pygy commentedon Mar 1, 2019
Also https://news.ycombinator.com/item?id=19283238
FWIW, I'm against this, I'd rather have proper recursive checking for
R.path(['foo', 'bar'], {foo: {bar: 5}}).On top of that, optional chaining is still a stage 1 proposal.
dusave commentedon Mar 1, 2019
I will be seeking Stage 2 for Optional Chaining at the next TC-39 meetup in March which, based on the outlook coming out of our November meetup, it should reach.
RyanCavanaugh commentedon Mar 2, 2019
I'm going to leave this open only because people get tend to get salty when they click on a link and see we closed something, but the definitive issue tracking this is #16 and we are (still!) committed to waiting for TC39 to decide what the semantics of this feature would be.
After being burned multiple times by adding features to TS only to have the semantic rug pulled out from under us at the last second, there is seriously no number of upvotes that would have us adding a feature that could potentially drastically change runtime behavior at some point in the future.
Nothing in that thread is not still true.
tlackemann commentedon Mar 2, 2019
We have been waiting on optional chaining for years. What semantics are honestly going to change? I'm not asking in a snarky way or in an insincere way, I just honestly don't understand what could possible change from 3-years ago to now to whenever this gets implemented.
RyanCavanaugh commentedon Mar 2, 2019
There are currently 29 open issues in the proposal repo, any one of which represents possible semantic changes, plus any new changes the committee might come up with.
From tc39/proposal-optional-chaining#2 / tc39/proposal-optional-chaining#10
undefined?.a.ban exception orundefined?(undefined?.a).ban exception orundefined?undefined?.a()an exception orundefined?a?.b()whenbisundefined?From tc39/proposal-optional-chaining#5
From tc39/proposal-optional-chaining#28
From tc39/proposal-optional-chaining#40
deleteoperator?tc39/proposal-optional-chaining#51
From tc39/proposal-optional-chaining#61
a.?bora?.b?From tc39/proposal-optional-chaining#69
null?.propresult inundefinedornull?dusave commentedon Mar 2, 2019
I completely concur with Ryan Cavanaugh (@RyanCavanaugh)'s assessment. We've come a long way and we're closer than ever, but part of the reason it's been such a long running proposal is the complexity around JavaScript, the semantics that exist and need to continue to work, and the readability/understandability of the code proposed.
One of the first things I plan to do once we reach Stage 2 is to go and clean out issues. As a semi-OCD person, this is going to scratch an itch I've had for awhile 😆. We simply didn't want to shut down discussions until we were a bit firmer in our approach, and Stage 2 will be that point.
I can also answer some of the above questions:
a?.b?.cfor static property lookupa?.[b]for dynamic property lookupa?.()for optional function executiondelete a?.bfor optional deletionundefinedbecause by that logic, you are looking forprop, which is not defined. You can be more verbose in your code if you care about getting thenull.I know most if not all of you are as excited as I am for this proposal. It's been a long road and I ask you wait just a little longer. These things take time, and since JavaScript is forever (once a proposal reaches Stage 4 and is officially part of the language, it can't be removed save for a security flaw), we want to make sure we've covered all the angles and considered all possibilities.
wintercounter commentedon Mar 2, 2019
Maybe this is the wrong place to discuss the proposal but why it simply couldn't be
?foo.bar.baz.buzRyanCavanaugh commentedon Mar 4, 2019
This is the wrong place to discuss the proposal 😉
nodkz commentedon Mar 4, 2019
@dustinsavery will be great if Optional Chaining will be split into several parts (if possible).
For example
static property accessmay become Stage-3 or even more Stage-4, this gives legitimacy to TS team for implementing this feature in near time.And other non-cozy parts like dynamic lookup, function execution, delete operator – may stay at Stage-1 or 2.
PS. Divide and conquer complex and loooong parts. 😉
dusave commentedon Mar 4, 2019
Paul Damnhorn (@nodkz) Trust me when I say we have tried many different angles to get this through. The fact that it hasn’t advanced isn’t for lack of trying or brainstorming new ideas or approaches. This is one that I tried during our last meeting, but that was voted down. We have a plan that has buyoff, now we just require patience from the community.
typescript-bot commentedon Mar 6, 2019
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
nodkz commentedon Mar 7, 2019
TypeScript Bot (@typescript-bot) holy life, you will close issues from us??? And we – the bags of blood and bones are nothing for you... Realy???
Ryan Cavanaugh (@RyanCavanaugh) @dustinsavery please alive this issue! and remove
duplicateto relax the typescripts's bot.I understand that complex questions better to keep closed by the bot... But it's too early to allow bots to take decisions in 2019...
#diversity #humanity_please_live #no_bots
RyanCavanaugh commentedon Mar 7, 2019
As a human, I approve the bot's behavior.