@@ -940,6 +940,7 @@ namespace ts {
940940 if (jsxPragma) {
941941 const chosenpragma = isArray(jsxPragma) ? jsxPragma[0] : jsxPragma;
942942 file.localJsxFactory = parseIsolatedEntityName(chosenpragma.arguments.factory, languageVersion);
943+ visitNode(file.localJsxFactory, markAsSynthetic);
943944 if (file.localJsxFactory) {
944945 return file.localJsxNamespace = getFirstIdentifier(file.localJsxFactory).escapedText;
945946 }
@@ -950,6 +951,7 @@ namespace ts {
950951 _jsxNamespace = "React" as __String;
951952 if (compilerOptions.jsxFactory) {
952953 _jsxFactoryEntity = parseIsolatedEntityName(compilerOptions.jsxFactory, languageVersion);
954+ visitNode(_jsxFactoryEntity, markAsSynthetic);
953955 if (_jsxFactoryEntity) {
954956 _jsxNamespace = getFirstIdentifier(_jsxFactoryEntity).escapedText;
955957 }
@@ -958,7 +960,16 @@ namespace ts {
958960 _jsxNamespace = escapeLeadingUnderscores(compilerOptions.reactNamespace);
959961 }
960962 }
963+ if (!_jsxFactoryEntity) {
964+ _jsxFactoryEntity = createQualifiedName(createIdentifier(unescapeLeadingUnderscores(_jsxNamespace)), "createElement");
965+ }
961966 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+ }
962973 }
963974
964975 function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken) {
@@ -2802,8 +2813,8 @@ namespace ts {
28022813 const namespaceMeaning = SymbolFlags.Namespace | (isInJSFile(name) ? meaning & SymbolFlags.Value : 0);
28032814 let symbol: Symbol | undefined;
28042815 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;
28072818 symbol = resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true);
28082819 if (!symbol) {
28092820 return symbolFromJSPrototype;
@@ -2846,7 +2857,7 @@ namespace ts {
28462857 throw Debug.assertNever(name, "Unknown entity name kind.");
28472858 }
28482859 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)) {
28502861 markSymbolOfAliasDeclarationIfTypeOnly(getAliasDeclarationFromName(name), symbol, /*finalTarget*/ undefined, /*overwriteEmpty*/ true);
28512862 }
28522863 return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol);
@@ -24391,7 +24402,7 @@ namespace ts {
2439124402 // can be specified by users through attributes property.
2439224403 const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
2439324404 const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*inferenceContext*/ undefined, checkMode);
24394- return checkTypeRelatedToAndOptionallyElaborate(
24405+ return checkTagNameDoesNotExpectTooManyArguments() && checkTypeRelatedToAndOptionallyElaborate(
2439524406 attributesType,
2439624407 paramType,
2439724408 relation,
@@ -24400,6 +24411,80 @@ namespace ts {
2440024411 /*headMessage*/ undefined,
2440124412 containingMessageChain,
2440224413 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+ }
2440324488 }
2440424489
2440524490 function getSignatureApplicabilityError(
@@ -35282,6 +35367,10 @@ namespace ts {
3528235367 return literalTypeToNode(<FreshableType>type, node, tracker);
3528335368 }
3528435369
35370+ function getJsxFactoryEntity(location: Node) {
35371+ return location ? (getJsxNamespace(location), (getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity;
35372+ }
35373+
3528535374 function createResolver(): EmitResolver {
3528635375 // this variable and functions that use it are deliberately moved here from the outer scope
3528735376 // to avoid scope pollution
@@ -35353,7 +35442,7 @@ namespace ts {
3535335442 const symbol = node && getSymbolOfNode(node);
3535435443 return !!(symbol && getCheckFlags(symbol) & CheckFlags.Late);
3535535444 },
35356- getJsxFactoryEntity: location => location ? (getJsxNamespace(location), (getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity ,
35445+ getJsxFactoryEntity,
3535735446 getAllAccessorDeclarations(accessor: AccessorDeclaration): AllAccessorDeclarations {
3535835447 accessor = getParseTreeNode(accessor, isGetOrSetAccessorDeclaration)!; // TODO: GH#18217
3535935448 const otherKind = accessor.kind === SyntaxKind.SetAccessor ? SyntaxKind.GetAccessor : SyntaxKind.SetAccessor;
0 commit comments