@@ -940,6 +940,7 @@ namespace ts {
940
940
if (jsxPragma) {
941
941
const chosenpragma = isArray(jsxPragma) ? jsxPragma[0] : jsxPragma;
942
942
file.localJsxFactory = parseIsolatedEntityName(chosenpragma.arguments.factory, languageVersion);
943
+ visitNode(file.localJsxFactory, markAsSynthetic);
943
944
if (file.localJsxFactory) {
944
945
return file.localJsxNamespace = getFirstIdentifier(file.localJsxFactory).escapedText;
945
946
}
@@ -950,6 +951,7 @@ namespace ts {
950
951
_jsxNamespace = "React" as __String;
951
952
if (compilerOptions.jsxFactory) {
952
953
_jsxFactoryEntity = parseIsolatedEntityName(compilerOptions.jsxFactory, languageVersion);
954
+ visitNode(_jsxFactoryEntity, markAsSynthetic);
953
955
if (_jsxFactoryEntity) {
954
956
_jsxNamespace = getFirstIdentifier(_jsxFactoryEntity).escapedText;
955
957
}
@@ -958,7 +960,16 @@ namespace ts {
958
960
_jsxNamespace = escapeLeadingUnderscores(compilerOptions.reactNamespace);
959
961
}
960
962
}
963
+ if (!_jsxFactoryEntity) {
964
+ _jsxFactoryEntity = createQualifiedName(createIdentifier(unescapeLeadingUnderscores(_jsxNamespace)), "createElement");
965
+ }
961
966
return _jsxNamespace;
967
+
968
+ function markAsSynthetic(node: Node): VisitResult<Node> {
969
+ node.pos = -1;
970
+ node.end = -1;
971
+ return visitEachChild(node, markAsSynthetic, nullTransformationContext);
972
+ }
962
973
}
963
974
964
975
function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken) {
@@ -2802,8 +2813,8 @@ namespace ts {
2802
2813
const namespaceMeaning = SymbolFlags.Namespace | (isInJSFile(name) ? meaning & SymbolFlags.Value : 0);
2803
2814
let symbol: Symbol | undefined;
2804
2815
if (name.kind === SyntaxKind.Identifier) {
2805
- const message = meaning === namespaceMeaning ? Diagnostics.Cannot_find_namespace_0 : getCannotFindNameDiagnosticForName(getFirstIdentifier(name));
2806
- const symbolFromJSPrototype = isInJSFile(name) ? resolveEntityNameFromAssignmentDeclaration(name, meaning) : undefined;
2816
+ const message = meaning === namespaceMeaning || nodeIsSynthesized(name) ? Diagnostics.Cannot_find_namespace_0 : getCannotFindNameDiagnosticForName(getFirstIdentifier(name));
2817
+ const symbolFromJSPrototype = isInJSFile(name) && !nodeIsSynthesized(name) ? resolveEntityNameFromAssignmentDeclaration(name, meaning) : undefined;
2807
2818
symbol = resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true);
2808
2819
if (!symbol) {
2809
2820
return symbolFromJSPrototype;
@@ -2846,7 +2857,7 @@ namespace ts {
2846
2857
throw Debug.assertNever(name, "Unknown entity name kind.");
2847
2858
}
2848
2859
Debug.assert((getCheckFlags(symbol) & CheckFlags.Instantiated) === 0, "Should never get an instantiated symbol here.");
2849
- if (isEntityName(name) && (symbol.flags & SymbolFlags.Alias || name.parent.kind === SyntaxKind.ExportAssignment)) {
2860
+ if (!nodeIsSynthesized(name) && isEntityName(name) && (symbol.flags & SymbolFlags.Alias || name.parent.kind === SyntaxKind.ExportAssignment)) {
2850
2861
markSymbolOfAliasDeclarationIfTypeOnly(getAliasDeclarationFromName(name), symbol, /*finalTarget*/ undefined, /*overwriteEmpty*/ true);
2851
2862
}
2852
2863
return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol);
@@ -24391,7 +24402,7 @@ namespace ts {
24391
24402
// can be specified by users through attributes property.
24392
24403
const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
24393
24404
const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*inferenceContext*/ undefined, checkMode);
24394
- return checkTypeRelatedToAndOptionallyElaborate(
24405
+ return checkTagNameDoesNotExpectTooManyArguments() && checkTypeRelatedToAndOptionallyElaborate(
24395
24406
attributesType,
24396
24407
paramType,
24397
24408
relation,
@@ -24400,6 +24411,80 @@ namespace ts {
24400
24411
/*headMessage*/ undefined,
24401
24412
containingMessageChain,
24402
24413
errorOutputContainer);
24414
+
24415
+ function checkTagNameDoesNotExpectTooManyArguments(): boolean {
24416
+ const tagType = isJsxOpeningElement(node) || isJsxSelfClosingElement(node) && !isJsxIntrinsicIdentifier(node.tagName) ? checkExpression(node.tagName) : undefined;
24417
+ if (!tagType) {
24418
+ return true;
24419
+ }
24420
+ const tagCallSignatures = getSignaturesOfType(tagType, SignatureKind.Call);
24421
+ if (!length(tagCallSignatures)) {
24422
+ return true;
24423
+ }
24424
+ const factory = getJsxFactoryEntity(node);
24425
+ if (!factory) {
24426
+ return true;
24427
+ }
24428
+ const factorySymbol = resolveEntityName(factory, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, node);
24429
+ if (!factorySymbol) {
24430
+ return true;
24431
+ }
24432
+
24433
+ const factoryType = getTypeOfSymbol(factorySymbol);
24434
+ const callSignatures = getSignaturesOfType(factoryType, SignatureKind.Call);
24435
+ if (!length(callSignatures)) {
24436
+ return true;
24437
+ }
24438
+
24439
+ let hasFirstParamSignatures = false;
24440
+ let maxParamCount = 0;
24441
+ // Check that _some_ first parameter expects a FC-like thing, and that some overload of the SFC expects an acceptable number of arguments
24442
+ for (const sig of callSignatures) {
24443
+ const firstparam = getTypeAtPosition(sig, 0);
24444
+ const signaturesOfParam = getSignaturesOfType(firstparam, SignatureKind.Call);
24445
+ if (!length(signaturesOfParam)) continue;
24446
+ for (const paramSig of signaturesOfParam) {
24447
+ hasFirstParamSignatures = true;
24448
+ if (hasEffectiveRestParameter(paramSig)) {
24449
+ return true; // some signature has a rest param, so function components can have an arbitrary number of arguments
24450
+ }
24451
+ const paramCount = getParameterCount(paramSig);
24452
+ if (paramCount > maxParamCount) {
24453
+ maxParamCount = paramCount;
24454
+ }
24455
+ }
24456
+ }
24457
+ if (!hasFirstParamSignatures) {
24458
+ // Not a single signature had a first parameter which expected a signature - for back compat, and
24459
+ // to guard against generic factories which won't have signatures directly, do not error
24460
+ return true;
24461
+ }
24462
+ let absoluteMinArgCount = Infinity;
24463
+ for (const tagSig of tagCallSignatures) {
24464
+ const tagRequiredArgCount = getMinArgumentCount(tagSig);
24465
+ if (tagRequiredArgCount < absoluteMinArgCount) {
24466
+ absoluteMinArgCount = tagRequiredArgCount;
24467
+ }
24468
+ }
24469
+ if (absoluteMinArgCount <= maxParamCount) {
24470
+ return true; // some signature accepts the number of arguments the function component provides
24471
+ }
24472
+
24473
+ if (reportErrors) {
24474
+ const diag = createDiagnosticForNode(node.tagName, Diagnostics.Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3, entityNameToString(node.tagName), absoluteMinArgCount, entityNameToString(factory), maxParamCount);
24475
+ const tagNameDeclaration = getSymbolAtLocation(node.tagName)?.valueDeclaration;
24476
+ if (tagNameDeclaration) {
24477
+ addRelatedInfo(diag, createDiagnosticForNode(tagNameDeclaration, Diagnostics._0_is_declared_here, entityNameToString(node.tagName)));
24478
+ }
24479
+ if (errorOutputContainer && errorOutputContainer.skipLogging) {
24480
+ (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
24481
+ }
24482
+ if (!errorOutputContainer.skipLogging) {
24483
+ diagnostics.add(diag);
24484
+ }
24485
+ }
24486
+ return false;
24487
+ }
24403
24488
}
24404
24489
24405
24490
function getSignatureApplicabilityError(
@@ -35282,6 +35367,10 @@ namespace ts {
35282
35367
return literalTypeToNode(<FreshableType>type, node, tracker);
35283
35368
}
35284
35369
35370
+ function getJsxFactoryEntity(location: Node) {
35371
+ return location ? (getJsxNamespace(location), (getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity;
35372
+ }
35373
+
35285
35374
function createResolver(): EmitResolver {
35286
35375
// this variable and functions that use it are deliberately moved here from the outer scope
35287
35376
// to avoid scope pollution
@@ -35353,7 +35442,7 @@ namespace ts {
35353
35442
const symbol = node && getSymbolOfNode(node);
35354
35443
return !!(symbol && getCheckFlags(symbol) & CheckFlags.Late);
35355
35444
},
35356
- getJsxFactoryEntity: location => location ? (getJsxNamespace(location), (getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity ,
35445
+ getJsxFactoryEntity,
35357
35446
getAllAccessorDeclarations(accessor: AccessorDeclaration): AllAccessorDeclarations {
35358
35447
accessor = getParseTreeNode(accessor, isGetOrSetAccessorDeclaration)!; // TODO: GH#18217
35359
35448
const otherKind = accessor.kind === SyntaxKind.SetAccessor ? SyntaxKind.GetAccessor : SyntaxKind.SetAccessor;
0 commit comments