@@ -320,6 +320,7 @@ import {
320320 getJSDocParameterTags,
321321 getJSDocRoot,
322322 getJSDocSatisfiesExpressionType,
323+ getJSDocSpecializeTag,
323324 getJSDocTags,
324325 getJSDocThisTag,
325326 getJSDocType,
@@ -828,7 +829,6 @@ import {
828829 JsxFlags,
829830 JsxFragment,
830831 JsxNamespacedName,
831- JsxOpeningElement,
832832 JsxOpeningFragment,
833833 JsxOpeningLikeElement,
834834 JsxReferenceKind,
@@ -34743,15 +34743,34 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3474334743 return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, getNodeLinks(node).resolvedSymbol, indexedAccessType, indexExpression, checkMode), node);
3474434744 }
3474534745
34746- function callLikeExpressionMayHaveTypeArguments(node: CallLikeExpression): node is CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningElement {
34746+ function callLikeExpressionMayHaveTypeArguments(node: CallLikeExpression): node is CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningLikeElement {
3474734747 return isCallOrNewExpression(node) || isTaggedTemplateExpression(node) || isJsxOpeningLikeElement(node);
3474834748 }
3474934749
34750+ function getTypeArgumentsForCallLikeExpression(node: CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningLikeElement) {
34751+ if (isSuperCall(node)) {
34752+ return undefined;
34753+ }
34754+ if (isInJSFile(node)) {
34755+ let { parent } = node;
34756+ if (isJsxElement(parent)) {
34757+ parent = parent.parent;
34758+ }
34759+ if (canHaveJSDoc(parent)) {
34760+ const specializeTag = getJSDocSpecializeTag(parent);
34761+ if (specializeTag) {
34762+ return specializeTag.typeArguments;
34763+ }
34764+ }
34765+ }
34766+ return node.typeArguments;
34767+ }
34768+
3475034769 function resolveUntypedCall(node: CallLikeExpression): Signature {
3475134770 if (callLikeExpressionMayHaveTypeArguments(node)) {
3475234771 // Check type arguments even though we will give an error that untyped calls may not accept type arguments.
3475334772 // This gets us diagnostics for the type arguments and marks them as referenced.
34754- forEach(node.typeArguments , checkSourceElement);
34773+ forEach(getTypeArgumentsForCallLikeExpression( node) , checkSourceElement);
3475534774 }
3475634775
3475734776 if (node.kind === SyntaxKind.TaggedTemplateExpression) {
@@ -35702,21 +35721,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3570235721 }
3570335722
3570435723 function resolveCall(node: CallLikeExpression, signatures: readonly Signature[], candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, callChainFlags: SignatureFlags, headMessage?: DiagnosticMessage): Signature {
35705- const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression;
3570635724 const isDecorator = node.kind === SyntaxKind.Decorator;
35707- const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node);
3570835725 const isInstanceof = node.kind === SyntaxKind.BinaryExpression;
3570935726 const reportErrors = !isInferencePartiallyBlocked && !candidatesOutArray;
3571035727
3571135728 let typeArguments: NodeArray<TypeNode> | undefined;
3571235729
35713- if (!isDecorator && !isInstanceof && !isSuperCall(node)) {
35714- typeArguments = (node as CallExpression).typeArguments;
35715-
35716- // We already perform checking on the type arguments on the class declaration itself.
35717- if (isTaggedTemplate || isJsxOpeningOrSelfClosingElement || (node as CallExpression).expression.kind !== SyntaxKind.SuperKeyword) {
35718- forEach(typeArguments, checkSourceElement);
35719- }
35730+ if (callLikeExpressionMayHaveTypeArguments(node)) {
35731+ typeArguments = getTypeArgumentsForCallLikeExpression(node);
35732+ forEach(typeArguments, checkSourceElement);
3572035733 }
3572135734
3572235735 const candidates = candidatesOutArray || [];
@@ -35888,7 +35901,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3588835901 diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args, headMessage));
3588935902 }
3589035903 else if (candidateForTypeArgumentError) {
35891- checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression | JsxOpeningLikeElement). typeArguments!, /*reportErrors*/ true, headMessage);
35904+ checkTypeArguments(candidateForTypeArgumentError, typeArguments!, /*reportErrors*/ true, headMessage);
3589235905 }
3589335906 else {
3589435907 const signaturesWithCorrectTypeArgumentArity = filter(signatures, s => hasCorrectTypeArgumentArity(s, typeArguments));
@@ -36102,7 +36115,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3610236115 return candidate;
3610336116 }
3610436117
36105- const typeArgumentNodes: readonly TypeNode[] | undefined = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments : undefined;
36118+ const typeArgumentNodes: readonly TypeNode[] | undefined = callLikeExpressionMayHaveTypeArguments(node) ? getTypeArgumentsForCallLikeExpression( node) : undefined;
3610636119 const instantiated = typeArgumentNodes
3610736120 ? createSignatureInstantiation(candidate, getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, isInJSFile(node)))
3610836121 : inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args, checkMode);
@@ -36202,14 +36215,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3620236215 // that the user will not add any.
3620336216 const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
3620436217 const numConstructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct).length;
36218+ const typeArguments = getTypeArgumentsForCallLikeExpression(node);
3620536219
3620636220 // TS 1.0 Spec: 4.12
3620736221 // In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
3620836222 // types are provided for the argument expressions, and the result is always of type Any.
3620936223 if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, numConstructSignatures)) {
3621036224 // The unknownType indicates that an error already occurred (and was reported). No
3621136225 // need to report another error in this case.
36212- if (!isErrorType(funcType) && node. typeArguments) {
36226+ if (!isErrorType(funcType) && typeArguments) {
3621336227 error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
3621436228 }
3621536229 return resolveUntypedCall(node);
@@ -36245,7 +36259,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3624536259 // use the resolvingSignature singleton to indicate that we deferred processing. This result will be
3624636260 // propagated out and eventually turned into silentNeverType (a type that is assignable to anything and
3624736261 // from which we never make inferences).
36248- if (checkMode & CheckMode.SkipGenericFunctions && !node. typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
36262+ if (checkMode & CheckMode.SkipGenericFunctions && !typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
3624936263 skippedGenericFunction(node, checkMode);
3625036264 return resolvingSignature;
3625136265 }
@@ -36290,11 +36304,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3629036304 return resolveErrorCall(node);
3629136305 }
3629236306
36307+ const typeArguments = getTypeArgumentsForCallLikeExpression(node);
3629336308 // TS 1.0 spec: 4.11
3629436309 // If expressionType is of type Any, Args can be any argument
3629536310 // list and the result of the operation is of type Any.
3629636311 if (isTypeAny(expressionType)) {
36297- if (node. typeArguments) {
36312+ if (typeArguments) {
3629836313 error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
3629936314 }
3630036315 return resolveUntypedCall(node);
@@ -36659,9 +36674,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3665936674 const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
3666036675 const fakeSignature = createSignatureForJSXIntrinsic(node, result);
3666136676 checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*inferenceContext*/ undefined, CheckMode.Normal), result, node.tagName, node.attributes);
36662- if (length(node.typeArguments)) {
36663- forEach(node.typeArguments, checkSourceElement);
36664- diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), node.typeArguments!, Diagnostics.Expected_0_type_arguments_but_got_1, 0, length(node.typeArguments)));
36677+ const typeArguments = getTypeArgumentsForCallLikeExpression(node);
36678+ if (length(typeArguments)) {
36679+ forEach(typeArguments, checkSourceElement);
36680+ diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments!, Diagnostics.Expected_0_type_arguments_but_got_1, 0, length(typeArguments)));
3666536681 }
3666636682 return fakeSignature;
3666736683 }
@@ -36917,7 +36933,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3691736933 * @returns On success, the expression's signature's return type. On failure, anyType.
3691836934 */
3691936935 function checkCallExpression(node: CallExpression | NewExpression, checkMode?: CheckMode): Type {
36920- checkGrammarTypeArguments(node, node.typeArguments );
36936+ checkGrammarTypeArguments(node, getTypeArgumentsForCallLikeExpression( node) );
3692136937
3692236938 const signature = getResolvedSignature(node, /*candidatesOutArray*/ undefined, checkMode);
3692336939 if (signature === resolvingSignature) {
@@ -37156,7 +37172,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3715637172 }
3715737173
3715837174 function checkTaggedTemplateExpression(node: TaggedTemplateExpression): Type {
37159- if (!checkGrammarTaggedTemplateChain(node)) checkGrammarTypeArguments(node, node.typeArguments);
37175+ if (!checkGrammarTaggedTemplateChain(node)) {
37176+ checkGrammarTypeArguments(node, getTypeArgumentsForCallLikeExpression(node));
37177+ }
3716037178 if (languageVersion < LanguageFeatureMinimumTarget.TaggedTemplates) {
3716137179 checkExternalEmitHelpers(node, ExternalEmitHelpers.MakeTemplateObject);
3716237180 }
@@ -41719,15 +41737,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4171941737 checkDecorators(node);
4172041738 }
4172141739
41722- function getEffectiveTypeArgumentAtIndex(node: TypeReferenceNode | ExpressionWithTypeArguments , typeParameters: readonly TypeParameter[], index: number): Type {
41740+ function getEffectiveTypeArgumentAtIndex(node: TypeReferenceNode, typeParameters: readonly TypeParameter[], index: number): Type {
4172341741 if (node.typeArguments && index < node.typeArguments.length) {
4172441742 return getTypeFromTypeNode(node.typeArguments[index]);
4172541743 }
4172641744 return getEffectiveTypeArguments(node, typeParameters)[index];
4172741745 }
4172841746
4172941747 function getEffectiveTypeArguments(node: TypeReferenceNode | ExpressionWithTypeArguments | NodeWithTypeArguments, typeParameters: readonly TypeParameter[]): Type[] {
41730- return fillMissingTypeArguments(map(node.typeArguments! , getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(node));
41748+ return fillMissingTypeArguments(map(node.typeArguments || [] , getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(node));
4173141749 }
4173241750
4173341751 function checkTypeArgumentConstraints(node: TypeReferenceNode | ExpressionWithTypeArguments | NodeWithTypeArguments, typeParameters: readonly TypeParameter[]): boolean {
@@ -51499,7 +51517,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
5149951517
5150051518 function checkGrammarJsxElement(node: JsxOpeningLikeElement) {
5150151519 checkGrammarJsxName(node.tagName);
51502- checkGrammarTypeArguments(node, node.typeArguments );
51520+ checkGrammarTypeArguments(node, getTypeArgumentsForCallLikeExpression( node) );
5150351521 const seen = new Map<__String, boolean>();
5150451522
5150551523 for (const attr of node.attributes.properties) {
0 commit comments