@@ -320,6 +320,7 @@ import {
320
320
getJSDocParameterTags,
321
321
getJSDocRoot,
322
322
getJSDocSatisfiesExpressionType,
323
+ getJSDocSpecializeTag,
323
324
getJSDocTags,
324
325
getJSDocThisTag,
325
326
getJSDocType,
@@ -828,7 +829,6 @@ import {
828
829
JsxFlags,
829
830
JsxFragment,
830
831
JsxNamespacedName,
831
- JsxOpeningElement,
832
832
JsxOpeningFragment,
833
833
JsxOpeningLikeElement,
834
834
JsxReferenceKind,
@@ -34743,15 +34743,34 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
34743
34743
return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, getNodeLinks(node).resolvedSymbol, indexedAccessType, indexExpression, checkMode), node);
34744
34744
}
34745
34745
34746
- function callLikeExpressionMayHaveTypeArguments(node: CallLikeExpression): node is CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningElement {
34746
+ function callLikeExpressionMayHaveTypeArguments(node: CallLikeExpression): node is CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningLikeElement {
34747
34747
return isCallOrNewExpression(node) || isTaggedTemplateExpression(node) || isJsxOpeningLikeElement(node);
34748
34748
}
34749
34749
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
+
34750
34769
function resolveUntypedCall(node: CallLikeExpression): Signature {
34751
34770
if (callLikeExpressionMayHaveTypeArguments(node)) {
34752
34771
// Check type arguments even though we will give an error that untyped calls may not accept type arguments.
34753
34772
// This gets us diagnostics for the type arguments and marks them as referenced.
34754
- forEach(node.typeArguments , checkSourceElement);
34773
+ forEach(getTypeArgumentsForCallLikeExpression( node) , checkSourceElement);
34755
34774
}
34756
34775
34757
34776
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
@@ -35702,21 +35721,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
35702
35721
}
35703
35722
35704
35723
function resolveCall(node: CallLikeExpression, signatures: readonly Signature[], candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, callChainFlags: SignatureFlags, headMessage?: DiagnosticMessage): Signature {
35705
- const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression;
35706
35724
const isDecorator = node.kind === SyntaxKind.Decorator;
35707
- const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node);
35708
35725
const isInstanceof = node.kind === SyntaxKind.BinaryExpression;
35709
35726
const reportErrors = !isInferencePartiallyBlocked && !candidatesOutArray;
35710
35727
35711
35728
let typeArguments: NodeArray<TypeNode> | undefined;
35712
35729
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);
35720
35733
}
35721
35734
35722
35735
const candidates = candidatesOutArray || [];
@@ -35888,7 +35901,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
35888
35901
diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args, headMessage));
35889
35902
}
35890
35903
else if (candidateForTypeArgumentError) {
35891
- checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression | JsxOpeningLikeElement). typeArguments!, /*reportErrors*/ true, headMessage);
35904
+ checkTypeArguments(candidateForTypeArgumentError, typeArguments!, /*reportErrors*/ true, headMessage);
35892
35905
}
35893
35906
else {
35894
35907
const signaturesWithCorrectTypeArgumentArity = filter(signatures, s => hasCorrectTypeArgumentArity(s, typeArguments));
@@ -36102,7 +36115,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
36102
36115
return candidate;
36103
36116
}
36104
36117
36105
- const typeArgumentNodes: readonly TypeNode[] | undefined = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments : undefined;
36118
+ const typeArgumentNodes: readonly TypeNode[] | undefined = callLikeExpressionMayHaveTypeArguments(node) ? getTypeArgumentsForCallLikeExpression( node) : undefined;
36106
36119
const instantiated = typeArgumentNodes
36107
36120
? createSignatureInstantiation(candidate, getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, isInJSFile(node)))
36108
36121
: inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args, checkMode);
@@ -36202,14 +36215,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
36202
36215
// that the user will not add any.
36203
36216
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
36204
36217
const numConstructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct).length;
36218
+ const typeArguments = getTypeArgumentsForCallLikeExpression(node);
36205
36219
36206
36220
// TS 1.0 Spec: 4.12
36207
36221
// In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
36208
36222
// types are provided for the argument expressions, and the result is always of type Any.
36209
36223
if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, numConstructSignatures)) {
36210
36224
// The unknownType indicates that an error already occurred (and was reported). No
36211
36225
// need to report another error in this case.
36212
- if (!isErrorType(funcType) && node. typeArguments) {
36226
+ if (!isErrorType(funcType) && typeArguments) {
36213
36227
error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
36214
36228
}
36215
36229
return resolveUntypedCall(node);
@@ -36245,7 +36259,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
36245
36259
// use the resolvingSignature singleton to indicate that we deferred processing. This result will be
36246
36260
// propagated out and eventually turned into silentNeverType (a type that is assignable to anything and
36247
36261
// 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)) {
36249
36263
skippedGenericFunction(node, checkMode);
36250
36264
return resolvingSignature;
36251
36265
}
@@ -36290,11 +36304,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
36290
36304
return resolveErrorCall(node);
36291
36305
}
36292
36306
36307
+ const typeArguments = getTypeArgumentsForCallLikeExpression(node);
36293
36308
// TS 1.0 spec: 4.11
36294
36309
// If expressionType is of type Any, Args can be any argument
36295
36310
// list and the result of the operation is of type Any.
36296
36311
if (isTypeAny(expressionType)) {
36297
- if (node. typeArguments) {
36312
+ if (typeArguments) {
36298
36313
error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
36299
36314
}
36300
36315
return resolveUntypedCall(node);
@@ -36659,9 +36674,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
36659
36674
const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
36660
36675
const fakeSignature = createSignatureForJSXIntrinsic(node, result);
36661
36676
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)));
36665
36681
}
36666
36682
return fakeSignature;
36667
36683
}
@@ -36917,7 +36933,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
36917
36933
* @returns On success, the expression's signature's return type. On failure, anyType.
36918
36934
*/
36919
36935
function checkCallExpression(node: CallExpression | NewExpression, checkMode?: CheckMode): Type {
36920
- checkGrammarTypeArguments(node, node.typeArguments );
36936
+ checkGrammarTypeArguments(node, getTypeArgumentsForCallLikeExpression( node) );
36921
36937
36922
36938
const signature = getResolvedSignature(node, /*candidatesOutArray*/ undefined, checkMode);
36923
36939
if (signature === resolvingSignature) {
@@ -37156,7 +37172,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
37156
37172
}
37157
37173
37158
37174
function checkTaggedTemplateExpression(node: TaggedTemplateExpression): Type {
37159
- if (!checkGrammarTaggedTemplateChain(node)) checkGrammarTypeArguments(node, node.typeArguments);
37175
+ if (!checkGrammarTaggedTemplateChain(node)) {
37176
+ checkGrammarTypeArguments(node, getTypeArgumentsForCallLikeExpression(node));
37177
+ }
37160
37178
if (languageVersion < LanguageFeatureMinimumTarget.TaggedTemplates) {
37161
37179
checkExternalEmitHelpers(node, ExternalEmitHelpers.MakeTemplateObject);
37162
37180
}
@@ -41719,15 +41737,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
41719
41737
checkDecorators(node);
41720
41738
}
41721
41739
41722
- function getEffectiveTypeArgumentAtIndex(node: TypeReferenceNode | ExpressionWithTypeArguments , typeParameters: readonly TypeParameter[], index: number): Type {
41740
+ function getEffectiveTypeArgumentAtIndex(node: TypeReferenceNode, typeParameters: readonly TypeParameter[], index: number): Type {
41723
41741
if (node.typeArguments && index < node.typeArguments.length) {
41724
41742
return getTypeFromTypeNode(node.typeArguments[index]);
41725
41743
}
41726
41744
return getEffectiveTypeArguments(node, typeParameters)[index];
41727
41745
}
41728
41746
41729
41747
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));
41731
41749
}
41732
41750
41733
41751
function checkTypeArgumentConstraints(node: TypeReferenceNode | ExpressionWithTypeArguments | NodeWithTypeArguments, typeParameters: readonly TypeParameter[]): boolean {
@@ -51499,7 +51517,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
51499
51517
51500
51518
function checkGrammarJsxElement(node: JsxOpeningLikeElement) {
51501
51519
checkGrammarJsxName(node.tagName);
51502
- checkGrammarTypeArguments(node, node.typeArguments );
51520
+ checkGrammarTypeArguments(node, getTypeArgumentsForCallLikeExpression( node) );
51503
51521
const seen = new Map<__String, boolean>();
51504
51522
51505
51523
for (const attr of node.attributes.properties) {
0 commit comments