@@ -223,6 +223,7 @@ namespace ts {
223223 visitNodes ( cbNode , cbNodes , ( < CallExpression > node ) . arguments ) ;
224224 case SyntaxKind . TaggedTemplateExpression :
225225 return visitNode ( cbNode , ( < TaggedTemplateExpression > node ) . tag ) ||
226+ visitNodes ( cbNode , cbNodes , ( < TaggedTemplateExpression > node ) . typeArguments ) ||
226227 visitNode ( cbNode , ( < TaggedTemplateExpression > node ) . template ) ;
227228 case SyntaxKind . TypeAssertionExpression :
228229 return visitNode ( cbNode , ( < TypeAssertion > node ) . type ) ||
@@ -4362,18 +4363,28 @@ namespace ts {
43624363 continue ;
43634364 }
43644365
4365- if ( token ( ) === SyntaxKind . NoSubstitutionTemplateLiteral || token ( ) === SyntaxKind . TemplateHead ) {
4366- const tagExpression = < TaggedTemplateExpression > createNode ( SyntaxKind . TaggedTemplateExpression , expression . pos ) ;
4367- tagExpression . tag = expression ;
4368- tagExpression . template = token ( ) === SyntaxKind . NoSubstitutionTemplateLiteral
4369- ? < NoSubstitutionTemplateLiteral > parseLiteralNode ( )
4370- : parseTemplateExpression ( ) ;
4371- expression = finishNode ( tagExpression ) ;
4366+ if ( isTemplateStartOfTaggedTemplate ( ) ) {
4367+ expression = parseTaggedTemplateRest ( expression , /*typeArguments*/ undefined ) ;
43724368 continue ;
43734369 }
43744370
43754371 return < MemberExpression > expression ;
43764372 }
4373+
4374+ }
4375+
4376+ function isTemplateStartOfTaggedTemplate ( ) {
4377+ return token ( ) === SyntaxKind . NoSubstitutionTemplateLiteral || token ( ) === SyntaxKind . TemplateHead ;
4378+ }
4379+
4380+ function parseTaggedTemplateRest ( tag : LeftHandSideExpression , typeArguments : NodeArray < TypeNode > | undefined ) {
4381+ const tagExpression = < TaggedTemplateExpression > createNode ( SyntaxKind . TaggedTemplateExpression , tag . pos ) ;
4382+ tagExpression . tag = tag ;
4383+ tagExpression . typeArguments = typeArguments ;
4384+ tagExpression . template = token ( ) === SyntaxKind . NoSubstitutionTemplateLiteral
4385+ ? < NoSubstitutionTemplateLiteral > parseLiteralNode ( )
4386+ : parseTemplateExpression ( ) ;
4387+ return finishNode ( tagExpression ) ;
43774388 }
43784389
43794390 function parseCallExpressionRest ( expression : LeftHandSideExpression ) : LeftHandSideExpression {
@@ -4389,6 +4400,11 @@ namespace ts {
43894400 return expression ;
43904401 }
43914402
4403+ if ( isTemplateStartOfTaggedTemplate ( ) ) {
4404+ expression = parseTaggedTemplateRest ( expression , typeArguments ) ;
4405+ continue ;
4406+ }
4407+
43924408 const callExpr = < CallExpression > createNode ( SyntaxKind . CallExpression , expression . pos ) ;
43934409 callExpr . expression = expression ;
43944410 callExpr . typeArguments = typeArguments ;
@@ -4436,8 +4452,10 @@ namespace ts {
44364452 function canFollowTypeArgumentsInExpression ( ) : boolean {
44374453 switch ( token ( ) ) {
44384454 case SyntaxKind . OpenParenToken : // foo<x>(
4439- // this case are the only case where this token can legally follow a type argument
4440- // list. So we definitely want to treat this as a type arg list.
4455+ case SyntaxKind . NoSubstitutionTemplateLiteral : // foo<T> `...`
4456+ case SyntaxKind . TemplateHead : // foo<T> `...${100}...`
4457+ // these are the only tokens can legally follow a type argument
4458+ // list. So we definitely want to treat them as type arg lists.
44414459
44424460 case SyntaxKind . DotToken : // foo<x>.
44434461 case SyntaxKind . CloseParenToken : // foo<x>)
0 commit comments