Skip to content

Optional chaining: (a?.b).c is parsed as a?.b.c #1139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
thorn0 opened this issue Oct 25, 2019 · 4 comments · Fixed by #1141
Closed

Optional chaining: (a?.b).c is parsed as a?.b.c #1139

thorn0 opened this issue Oct 25, 2019 · 4 comments · Fixed by #1141
Labels
bug Something isn't working has pr there is a PR raised to close this package: typescript-estree Issues related to @typescript-eslint/typescript-estree

Comments

@thorn0
Copy link
Contributor

thorn0 commented Oct 25, 2019

prettier/prettier#6657 is blocked by this issue.

What code were you trying to parse?

(a?.b).c

What did you expect to happen?

The outer node should be of type MemberExpresion, not OptionalMemberExpression.

What actually happened?

Both member expressions are OptionalMemberExpression as if the parens weren't there (a?.b.c).

Versions

package version
@typescript-eslint/typescript-estree 2.5.1-alpha.3
TypeScript 3.7.0-rc
node 10.15.0
npm 6.11.3
@thorn0 thorn0 added package: typescript-estree Issues related to @typescript-eslint/typescript-estree triage Waiting for team members to take a look labels Oct 25, 2019
@bradzacher
Copy link
Member

bradzacher commented Oct 25, 2019

I don't understand why babel handles this case differently.

It seems to me like this is semantically no different.
Unless I'm mistaken, the parenthesis don't actually change the output or order of execution?

@bradzacher bradzacher added bug Something isn't working and removed triage Waiting for team members to take a look labels Oct 25, 2019
@thorn0
Copy link
Contributor Author

thorn0 commented Oct 25, 2019

TS compiles

  • a?.b.c to: (_a = a) === null || _a === void 0 ? void 0 : _a.b.c
  • (a?.b).c to: ((_a = a) === null || _a === void 0 ? void 0 : _a.b).c

playground

@bradzacher
Copy link
Member

bradzacher commented Oct 25, 2019

Hmmm yes, I am mistaken - it does change the order of execution and thus the return values and types.

type T = Record<string, Record<string, string>>;
declare const x: T | undefined;

const v1 = x?.a.b;
const v2 = (x?.a).b;
//         ^^^^^^ Object is possibly 'undefined'.
const v3 = (x?.a)?.b;

@thorn0
Copy link
Contributor Author

thorn0 commented Oct 25, 2019

Yep, it's tricky.

@bradzacher bradzacher added the has pr there is a PR raised to close this label Oct 25, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working has pr there is a PR raised to close this package: typescript-estree Issues related to @typescript-eslint/typescript-estree
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants