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
fix: optional-chaining should work correctly with ts non-null operator #10961
fix: optional-chaining should work correctly with ts non-null operator #10961
Conversation
49a4708
to
98c1799
Compare
if (optionalPath.isTSNonNullExpression()) { | ||
optionalPath.replaceWith(optionalPath.node.expression); | ||
|
||
if (optionalPath.isOptionalMemberExpression()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should only unwrap TSNonNullExpression and leave the node.expression
as-is. Because the non-null expression does not imply any runtime checks, which is done by the optional member.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, yeah. I tested now removing this if
block and works fine. Okay, I'm updating this PR. Thank you.
98c1799
to
029b658
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also add a test with:
- Optional chaining transform and typescript syntax only
- Optional chaining syntax only and typescript transform
@nicolo-ribaudo could you explain for me these |
@macabeus The
So this is to say, one wants to desugar
In this case one wants to remove TypeScript stuffs but leave optional-chaining as-is. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blocking this until we get confirmation from Typescript. @DanielRosenwasser?
Currently, Babel's transform matches Typescript's: http://www.typescriptlang.org/play/?ssl=1&ssc=1&pln=1&pc=8#code/IYfgdARghGDGQ
Note: I think we should change this, just need to confirm.
I agree that we should follow the output in |
@jridgewell It’s labeled as a bug in the TypeScript repo now. I think we’re good to go. |
Wait, no merger yet. We need to add the tests that @nicolo-ribaudo said. |
029b658
to
f56f54b
Compare
@nicolo-ribaudo Done. I added the two tests that you requested. |
Some random testes failed... but it's sounds like a false negative, because I just added more tests that works fine locally. I didn't changed anymore. |
@macabeus The CI error is not related. I will fix that later. |
{ | ||
"plugins": [ | ||
"../../../../../babel-plugin-syntax-optional-chaining", | ||
"../../../../../babel-plugin-transform-typescript" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use
"../../../../../babel-plugin-transform-typescript" | |
"transform-typescript" |
directly (and also for the other options.json
files)
@@ -0,0 +1,3 @@ | |||
var _a; | |||
|
|||
(_a = a) === null || _a === void 0 ? void 0 : _a.b.c; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we aren't transforming TypeScript, this should remain
(_a = a) === null || _a === void 0 ? void 0 : _a.b.c; | |
(_a = a) === null || _a === void 0 ? void 0 : _a.b!.c; |
However, I think that no one will ever find this bug so if it's too hard to fix I'm ok with opening a new issue and not fixing it in this PR.
The fix was just merged on TS: microsoft/TypeScript#36539 |
|
||
// unwrap a TSNonNullExpression if need | ||
if (optionalPath.isTSNonNullExpression()) { | ||
optionalPath.replaceWith(optionalPath.node.expression); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that this will correctly fix the bug. We may be able to see it more in test cases like a?.b!.c.d
and a?.b.c!.d
f56f54b
to
d490b96
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebased and added a lot of tests!
This is technically a breaking change, because it drops support for TypeScript 3.8. However, without merging this PR we can't support TypeScript 3.9. I don't think we should wait for Babel 8: does anyone thinks that it would be better to merge this in a minor rather than in the next patch? |
@nicolo-ribaudo Well... TS already merged that on a minor release: |
I'm good with a minor. |
This PR fix when use
!
operator within an optional chaining.should be compiled to
But previous this fix, it was compiling to
That could raise wrongly an exception if
a
isnull
orundefined
.The approach to fix this bug is unwrapping
TSNonNullExpression
on theOptionalMemberExpression
.