@@ -326,6 +326,7 @@ import {
326326 getJSDocParameterTags,
327327 getJSDocRoot,
328328 getJSDocSatisfiesExpressionType,
329+ getJSDocSpecializeTag,
329330 getJSDocTags,
330331 getJSDocThisTag,
331332 getJSDocType,
@@ -35562,15 +35563,34 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3556235563 return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, getNodeLinks(node).resolvedSymbol, indexedAccessType, indexExpression, checkMode), node);
3556335564 }
3556435565
35565- function callLikeExpressionMayHaveTypeArguments(node: CallLikeExpression): node is CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningElement {
35566+ function callLikeExpressionMayHaveTypeArguments(node: CallLikeExpression): node is CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningLikeElement {
3556635567 return isCallOrNewExpression(node) || isTaggedTemplateExpression(node) || isJsxOpeningLikeElement(node);
3556735568 }
3556835569
35570+ function getTypeArgumentsForCallLikeExpression(node: CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningLikeElement) {
35571+ if (isSuperCall(node)) {
35572+ return undefined;
35573+ }
35574+ if (isInJSFile(node)) {
35575+ let { parent } = node;
35576+ if (isJsxElement(parent)) {
35577+ parent = parent.parent;
35578+ }
35579+ if (canHaveJSDoc(parent)) {
35580+ const specializeTag = getJSDocSpecializeTag(parent);
35581+ if (specializeTag) {
35582+ return specializeTag.typeArguments;
35583+ }
35584+ }
35585+ }
35586+ return node.typeArguments;
35587+ }
35588+
3556935589 function resolveUntypedCall(node: CallLikeExpression): Signature {
3557035590 if (callLikeExpressionMayHaveTypeArguments(node)) {
3557135591 // Check type arguments even though we will give an error that untyped calls may not accept type arguments.
3557235592 // This gets us diagnostics for the type arguments and marks them as referenced.
35573- forEach(node.typeArguments , checkSourceElement);
35593+ forEach(getTypeArgumentsForCallLikeExpression( node) , checkSourceElement);
3557435594 }
3557535595
3557635596 if (node.kind === SyntaxKind.TaggedTemplateExpression) {
@@ -36570,13 +36590,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3657036590
3657136591 let candidates: Signature[] = [];
3657236592 let typeArguments: NodeArray<TypeNode> | undefined;
36573- if (!isDecorator && !isInstanceof && !isSuperCall(node) && !isJsxOpenFragment) {
36574- typeArguments = (node as CallExpression).typeArguments;
36575-
36576- // We already perform checking on the type arguments on the class declaration itself.
36577- if (isTaggedTemplate || isJsxOpeningOrSelfClosingElement || (node as CallExpression).expression.kind !== SyntaxKind.SuperKeyword) {
36578- forEach(typeArguments, checkSourceElement);
36579- }
36593+ if (callLikeExpressionMayHaveTypeArguments(node)) {
36594+ typeArguments = getTypeArgumentsForCallLikeExpression(node);
36595+ forEach(typeArguments, checkSourceElement);
3658036596 }
3658136597
3658236598 candidates = candidatesOutArray || [];
@@ -36748,7 +36764,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3674836764 diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args, headMessage));
3674936765 }
3675036766 else if (candidateForTypeArgumentError) {
36751- checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression | JsxOpeningLikeElement). typeArguments!, /*reportErrors*/ true, headMessage);
36767+ checkTypeArguments(candidateForTypeArgumentError, typeArguments!, /*reportErrors*/ true, headMessage);
3675236768 }
3675336769 else if (!isJsxOpenFragment) {
3675436770 const signaturesWithCorrectTypeArgumentArity = filter(signatures, s => hasCorrectTypeArgumentArity(s, typeArguments));
@@ -36953,7 +36969,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3695336969 return candidate;
3695436970 }
3695536971
36956- const typeArgumentNodes: readonly TypeNode[] | undefined = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments : undefined;
36972+ const typeArgumentNodes: readonly TypeNode[] | undefined = callLikeExpressionMayHaveTypeArguments(node) ? getTypeArgumentsForCallLikeExpression( node) : undefined;
3695736973 const instantiated = typeArgumentNodes
3695836974 ? createSignatureInstantiation(candidate, getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, isInJSFile(node)))
3695936975 : inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args, checkMode);
@@ -37053,14 +37069,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3705337069 // that the user will not add any.
3705437070 const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
3705537071 const numConstructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct).length;
37072+ const typeArguments = getTypeArgumentsForCallLikeExpression(node);
3705637073
3705737074 // TS 1.0 Spec: 4.12
3705837075 // In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
3705937076 // types are provided for the argument expressions, and the result is always of type Any.
3706037077 if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, numConstructSignatures)) {
3706137078 // The unknownType indicates that an error already occurred (and was reported). No
3706237079 // need to report another error in this case.
37063- if (!isErrorType(funcType) && node. typeArguments) {
37080+ if (!isErrorType(funcType) && typeArguments) {
3706437081 error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
3706537082 }
3706637083 return resolveUntypedCall(node);
@@ -37096,7 +37113,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3709637113 // use the resolvingSignature singleton to indicate that we deferred processing. This result will be
3709737114 // propagated out and eventually turned into silentNeverType (a type that is assignable to anything and
3709837115 // from which we never make inferences).
37099- if (checkMode & CheckMode.SkipGenericFunctions && !node. typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
37116+ if (checkMode & CheckMode.SkipGenericFunctions && !typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
3710037117 skippedGenericFunction(node, checkMode);
3710137118 return resolvingSignature;
3710237119 }
@@ -37141,11 +37158,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3714137158 return resolveErrorCall(node);
3714237159 }
3714337160
37161+ const typeArguments = getTypeArgumentsForCallLikeExpression(node);
3714437162 // TS 1.0 spec: 4.11
3714537163 // If expressionType is of type Any, Args can be any argument
3714637164 // list and the result of the operation is of type Any.
3714737165 if (isTypeAny(expressionType)) {
37148- if (node. typeArguments) {
37166+ if (typeArguments) {
3714937167 error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
3715037168 }
3715137169 return resolveUntypedCall(node);
@@ -37545,9 +37563,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3754537563 const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
3754637564 const fakeSignature = createSignatureForJSXIntrinsic(node, result);
3754737565 checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*inferenceContext*/ undefined, CheckMode.Normal), result, node.tagName, node.attributes);
37548- if (length(node.typeArguments)) {
37549- forEach(node.typeArguments, checkSourceElement);
37550- diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), node.typeArguments!, Diagnostics.Expected_0_type_arguments_but_got_1, 0, length(node.typeArguments)));
37566+ const typeArguments = getTypeArgumentsForCallLikeExpression(node);
37567+ if (length(typeArguments)) {
37568+ forEach(typeArguments, checkSourceElement);
37569+ diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments!, Diagnostics.Expected_0_type_arguments_but_got_1, 0, length(typeArguments)));
3755137570 }
3755237571 return fakeSignature;
3755337572 }
@@ -37804,7 +37823,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3780437823 * @returns On success, the expression's signature's return type. On failure, anyType.
3780537824 */
3780637825 function checkCallExpression(node: CallExpression | NewExpression, checkMode?: CheckMode): Type {
37807- checkGrammarTypeArguments(node, node.typeArguments );
37826+ checkGrammarTypeArguments(node, getTypeArgumentsForCallLikeExpression( node) );
3780837827
3780937828 const signature = getResolvedSignature(node, /*candidatesOutArray*/ undefined, checkMode);
3781037829 if (signature === resolvingSignature) {
@@ -38043,7 +38062,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3804338062 }
3804438063
3804538064 function checkTaggedTemplateExpression(node: TaggedTemplateExpression): Type {
38046- if (!checkGrammarTaggedTemplateChain(node)) checkGrammarTypeArguments(node, node.typeArguments );
38065+ if (!checkGrammarTaggedTemplateChain(node)) checkGrammarTypeArguments(node, getTypeArgumentsForCallLikeExpression( node) );
3804738066 if (languageVersion < LanguageFeatureMinimumTarget.TaggedTemplates) {
3804838067 checkExternalEmitHelpers(node, ExternalEmitHelpers.MakeTemplateObject);
3804938068 }
@@ -42661,7 +42680,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4266142680 }
4266242681
4266342682 function getEffectiveTypeArguments(node: TypeReferenceNode | ExpressionWithTypeArguments | NodeWithTypeArguments, typeParameters: readonly TypeParameter[]): Type[] {
42664- return fillMissingTypeArguments(map(node.typeArguments! , getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(node));
42683+ return fillMissingTypeArguments(map(node.typeArguments || [] , getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(node));
4266542684 }
4266642685
4266742686 function checkTypeArgumentConstraints(node: TypeReferenceNode | ExpressionWithTypeArguments | NodeWithTypeArguments, typeParameters: readonly TypeParameter[]): boolean {
@@ -52696,7 +52715,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
5269652715
5269752716 function checkGrammarJsxElement(node: JsxOpeningLikeElement) {
5269852717 checkGrammarJsxName(node.tagName);
52699- checkGrammarTypeArguments(node, node.typeArguments );
52718+ checkGrammarTypeArguments(node, getTypeArgumentsForCallLikeExpression( node) );
5270052719 const seen = new Map<__String, boolean>();
5270152720
5270252721 for (const attr of node.attributes.properties) {
0 commit comments