@@ -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);
@@ -24389,7 +24400,7 @@ namespace ts {
24389
24400
// can be specified by users through attributes property.
24390
24401
const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
24391
24402
const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*inferenceContext*/ undefined, checkMode);
24392
- return checkTypeRelatedToAndOptionallyElaborate(
24403
+ return checkTagNameDoesNotExpectTooManyArguments() && checkTypeRelatedToAndOptionallyElaborate(
24393
24404
attributesType,
24394
24405
paramType,
24395
24406
relation,
@@ -24398,6 +24409,80 @@ namespace ts {
24398
24409
/*headMessage*/ undefined,
24399
24410
containingMessageChain,
24400
24411
errorOutputContainer);
24412
+
24413
+ function checkTagNameDoesNotExpectTooManyArguments(): boolean {
24414
+ const tagType = isJsxOpeningElement(node) || isJsxSelfClosingElement(node) && !isJsxIntrinsicIdentifier(node.tagName) ? checkExpression(node.tagName) : undefined;
24415
+ if (!tagType) {
24416
+ return true;
24417
+ }
24418
+ const tagCallSignatures = getSignaturesOfType(tagType, SignatureKind.Call);
24419
+ if (!length(tagCallSignatures)) {
24420
+ return true;
24421
+ }
24422
+ const factory = getJsxFactoryEntity(node);
24423
+ if (!factory) {
24424
+ return true;
24425
+ }
24426
+ const factorySymbol = resolveEntityName(factory, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, node);
24427
+ if (!factorySymbol) {
24428
+ return true;
24429
+ }
24430
+
24431
+ const factoryType = getTypeOfSymbol(factorySymbol);
24432
+ const callSignatures = getSignaturesOfType(factoryType, SignatureKind.Call);
24433
+ if (!length(callSignatures)) {
24434
+ return true;
24435
+ }
24436
+
24437
+ let hasFirstParamSignatures = false;
24438
+ let maxParamCount = 0;
24439
+ // Check that _some_ first parameter expects a FC-like thing, and that some overload of the SFC expects an acceptable number of arguments
24440
+ for (const sig of callSignatures) {
24441
+ const firstparam = getTypeAtPosition(sig, 0);
24442
+ const signaturesOfParam = getSignaturesOfType(firstparam, SignatureKind.Call);
24443
+ if (!length(signaturesOfParam)) continue;
24444
+ for (const paramSig of signaturesOfParam) {
24445
+ hasFirstParamSignatures = true;
24446
+ if (hasEffectiveRestParameter(paramSig)) {
24447
+ return true; // some signature has a rest param, so function components can have an arbitrary number of arguments
24448
+ }
24449
+ const paramCount = getParameterCount(paramSig);
24450
+ if (paramCount > maxParamCount) {
24451
+ maxParamCount = paramCount;
24452
+ }
24453
+ }
24454
+ }
24455
+ if (!hasFirstParamSignatures) {
24456
+ // Not a single signature had a first parameter which expected a signature - for back compat, and
24457
+ // to guard against generic factories which won't have signatures directly, do not error
24458
+ return true;
24459
+ }
24460
+ let absoluteMinArgCount = Infinity;
24461
+ for (const tagSig of tagCallSignatures) {
24462
+ const tagRequiredArgCount = getMinArgumentCount(tagSig);
24463
+ if (tagRequiredArgCount < absoluteMinArgCount) {
24464
+ absoluteMinArgCount = tagRequiredArgCount;
24465
+ }
24466
+ }
24467
+ if (absoluteMinArgCount <= maxParamCount) {
24468
+ return true; // some signature accepts the number of arguments the function component provides
24469
+ }
24470
+
24471
+ if (reportErrors) {
24472
+ 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);
24473
+ const tagNameDeclaration = getSymbolAtLocation(node.tagName)?.valueDeclaration;
24474
+ if (tagNameDeclaration) {
24475
+ addRelatedInfo(diag, createDiagnosticForNode(tagNameDeclaration, Diagnostics._0_is_declared_here, entityNameToString(node.tagName)));
24476
+ }
24477
+ if (errorOutputContainer && errorOutputContainer.skipLogging) {
24478
+ (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
24479
+ }
24480
+ if (!errorOutputContainer.skipLogging) {
24481
+ diagnostics.add(diag);
24482
+ }
24483
+ }
24484
+ return false;
24485
+ }
24401
24486
}
24402
24487
24403
24488
function getSignatureApplicabilityError(
@@ -35276,6 +35361,10 @@ namespace ts {
35276
35361
return literalTypeToNode(<FreshableType>type, node, tracker);
35277
35362
}
35278
35363
35364
+ function getJsxFactoryEntity(location: Node) {
35365
+ return location ? (getJsxNamespace(location), (getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity;
35366
+ }
35367
+
35279
35368
function createResolver(): EmitResolver {
35280
35369
// this variable and functions that use it are deliberately moved here from the outer scope
35281
35370
// to avoid scope pollution
@@ -35347,7 +35436,7 @@ namespace ts {
35347
35436
const symbol = node && getSymbolOfNode(node);
35348
35437
return !!(symbol && getCheckFlags(symbol) & CheckFlags.Late);
35349
35438
},
35350
- getJsxFactoryEntity: location => location ? (getJsxNamespace(location), (getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity ,
35439
+ getJsxFactoryEntity,
35351
35440
getAllAccessorDeclarations(accessor: AccessorDeclaration): AllAccessorDeclarations {
35352
35441
accessor = getParseTreeNode(accessor, isGetOrSetAccessorDeclaration)!; // TODO: GH#18217
35353
35442
const otherKind = accessor.kind === SyntaxKind.SetAccessor ? SyntaxKind.GetAccessor : SyntaxKind.SetAccessor;
0 commit comments