Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions tsc/internal/transformers/estransforms/optionalchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ func flattenChain(chain *ast.Node) flattenResult {
debug.Assert(!isNonNullChain(chain))
links = append([]*ast.Node{chain}, links...)
}
if ast.IsTaggedTemplateExpression(chain) {
// A tagged template has no expression; its tag is the base of the chain.
return flattenResult{chain.AsTaggedTemplateExpression().Tag, links}
}
return flattenResult{chain.Expression(), links}
}

Expand Down Expand Up @@ -204,6 +208,17 @@ func (ch *optionalChainTransformer) visitOptionalExpression(node *ast.Node, capt
ast.NodeFlagsNone,
)
}
case ast.KindTaggedTemplateExpression:
// A tagged template can only be the head of the chain (flattenChain
// stops walking at it); re-tag its template onto the checked base.
t := segment.AsTaggedTemplateExpression()
rightExpression = ch.Factory().NewTaggedTemplateExpression(
rightExpression,
nil, /*questionDotToken*/
t.TypeArguments,
ch.Visitor().VisitNode(t.Template),
ast.NodeFlagsNone,
)
}
ch.EmitContext().SetOriginal(rightExpression, segment)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
repro.ts(1,1): error TS2304: Cannot find name 'e'.
repro.ts(2,1): error TS1005: ')' expected.
siblings.ts(2,5): error TS1358: Tagged template expressions are not permitted in an optional chain.
siblings.ts(3,5): error TS1358: Tagged template expressions are not permitted in an optional chain.
siblings.ts(4,4): error TS1358: Tagged template expressions are not permitted in an optional chain.


==== repro.ts (2 errors) ====
e?.``(
~
!!! error TS2304: Cannot find name 'e'.


!!! error TS1005: ')' expected.
==== siblings.ts (3 errors) ====
declare var a: any;
a?.b`c`;
~~~
!!! error TS1358: Tagged template expressions are not permitted in an optional chain.
a?.b`c`();
~~~
!!! error TS1358: Tagged template expressions are not permitted in an optional chain.
a?.``.x;
~~
!!! error TS1358: Tagged template expressions are not permitted in an optional chain.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//// [tests/cases/compiler/optionalChainTaggedTemplate.ts] ////

//// [repro.ts]
e?.``(

//// [siblings.ts]
declare var a: any;
a?.b`c`;
a?.b`c`();
a?.``.x;


//// [repro.js]
"use strict";
e === null || e === void 0 ? void 0 : e ``();
//// [siblings.js]
"use strict";
var _a;
(a === null || a === void 0 ? void 0 : a.b) `c`;
(_a = a === null || a === void 0 ? void 0 : a.b) === null || _a === void 0 ? void 0 : _a `c`();
a === null || a === void 0 ? void 0 : a ``.x;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//// [tests/cases/compiler/optionalChainTaggedTemplate.ts] ////

=== repro.ts ===

e?.``(

=== siblings.ts ===
declare var a: any;
>a : Symbol(a, Decl(siblings.ts, 0, 11))

a?.b`c`;
>a : Symbol(a, Decl(siblings.ts, 0, 11))

a?.b`c`();
>a : Symbol(a, Decl(siblings.ts, 0, 11))

a?.``.x;
>a : Symbol(a, Decl(siblings.ts, 0, 11))

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//// [tests/cases/compiler/optionalChainTaggedTemplate.ts] ////

=== repro.ts ===
e?.``(
>e?.``( : any
>e?.`` : any
>e : any
>`` : ""

=== siblings.ts ===
declare var a: any;
>a : any

a?.b`c`;
>a?.b`c` : any
>a?.b : any
>a : any
>b : any
>`c` : "c"

a?.b`c`();
>a?.b`c`() : any
>a?.b`c` : any
>a?.b : any
>a : any
>b : any
>`c` : "c"

a?.``.x;
>a?.``.x : any
>a?.`` : any
>a : any
>`` : ""
>x : any

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
repro.ts(1,1): error TS2304: Cannot find name 'e'.
repro.ts(2,1): error TS1005: ')' expected.
siblings.ts(2,5): error TS1358: Tagged template expressions are not permitted in an optional chain.
siblings.ts(3,5): error TS1358: Tagged template expressions are not permitted in an optional chain.
siblings.ts(4,4): error TS1358: Tagged template expressions are not permitted in an optional chain.


==== repro.ts (2 errors) ====
e?.``(
~
!!! error TS2304: Cannot find name 'e'.


!!! error TS1005: ')' expected.
==== siblings.ts (3 errors) ====
declare var a: any;
a?.b`c`;
~~~
!!! error TS1358: Tagged template expressions are not permitted in an optional chain.
a?.b`c`();
~~~
!!! error TS1358: Tagged template expressions are not permitted in an optional chain.
a?.``.x;
~~
!!! error TS1358: Tagged template expressions are not permitted in an optional chain.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//// [tests/cases/compiler/optionalChainTaggedTemplate.ts] ////

//// [repro.ts]
e?.``(

//// [siblings.ts]
declare var a: any;
a?.b`c`;
a?.b`c`();
a?.``.x;


//// [repro.js]
"use strict";
e ``();
//// [siblings.js]
"use strict";
(a?.b) `c`;
(a?.b) `c`();
a ``.x;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//// [tests/cases/compiler/optionalChainTaggedTemplate.ts] ////

=== repro.ts ===

e?.``(

=== siblings.ts ===
declare var a: any;
>a : Symbol(a, Decl(siblings.ts, 0, 11))

a?.b`c`;
>a : Symbol(a, Decl(siblings.ts, 0, 11))

a?.b`c`();
>a : Symbol(a, Decl(siblings.ts, 0, 11))

a?.``.x;
>a : Symbol(a, Decl(siblings.ts, 0, 11))

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//// [tests/cases/compiler/optionalChainTaggedTemplate.ts] ////

=== repro.ts ===
e?.``(
>e?.``( : any
>e?.`` : any
>e : any
>`` : ""

=== siblings.ts ===
declare var a: any;
>a : any

a?.b`c`;
>a?.b`c` : any
>a?.b : any
>a : any
>b : any
>`c` : "c"

a?.b`c`();
>a?.b`c`() : any
>a?.b`c` : any
>a?.b : any
>a : any
>b : any
>`c` : "c"

a?.``.x;
>a?.``.x : any
>a?.`` : any
>a : any
>`` : ""
>x : any

10 changes: 10 additions & 0 deletions tsc/testdata/tests/cases/compiler/optionalChainTaggedTemplate.ts

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: can we rename this to something that doesn't say "no crash"?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to optionalChainTaggedTemplate.ts.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// @target: es2017, es2024

// @filename: repro.ts
e?.``(

// @filename: siblings.ts
declare var a: any;
a?.b`c`;
a?.b`c`();
a?.``.x;