From 0009efcd7c3bb9a9dcc378e61c8a9950921a2e20 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Wed, 4 Sep 2024 16:21:09 -0700 Subject: [PATCH 01/16] test case (before) --- .../jsxChildWrongFragment.errors.txt | 18 +++++++ .../reference/jsxChildWrongFragment.js | 24 ++++++++++ .../reference/jsxChildWrongFragment.symbols | 25 ++++++++++ .../reference/jsxChildWrongFragment.types | 47 +++++++++++++++++++ .../cases/compiler/jsxChildWrongFragment.tsx | 19 ++++++++ 5 files changed, 133 insertions(+) create mode 100644 tests/baselines/reference/jsxChildWrongFragment.errors.txt create mode 100644 tests/baselines/reference/jsxChildWrongFragment.js create mode 100644 tests/baselines/reference/jsxChildWrongFragment.symbols create mode 100644 tests/baselines/reference/jsxChildWrongFragment.types create mode 100644 tests/cases/compiler/jsxChildWrongFragment.tsx diff --git a/tests/baselines/reference/jsxChildWrongFragment.errors.txt b/tests/baselines/reference/jsxChildWrongFragment.errors.txt new file mode 100644 index 0000000000000..55cb3372248a4 --- /dev/null +++ b/tests/baselines/reference/jsxChildWrongFragment.errors.txt @@ -0,0 +1,18 @@ +index.tsx(10,47): error TS2322: Type '() => string' is not assignable to type 'ReactNode'. + + +==== index.tsx (1 errors) ==== + /// + /// + + const test = () => "asd"; + + // No Errors + const jsxWithJsxFragment = <>{test}; + + // Type '() => string' is not assignable to type 'ReactNode'. + const jsxWithReactFragment = {test}; + ~~~~ +!!! error TS2322: Type '() => string' is not assignable to type 'ReactNode'. +!!! related TS6212 index.tsx:10:47: Did you mean to call this expression? + \ No newline at end of file diff --git a/tests/baselines/reference/jsxChildWrongFragment.js b/tests/baselines/reference/jsxChildWrongFragment.js new file mode 100644 index 0000000000000..dd3c3c5731a8b --- /dev/null +++ b/tests/baselines/reference/jsxChildWrongFragment.js @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/jsxChildWrongFragment.tsx] //// + +//// [index.tsx] +/// +/// + +const test = () => "asd"; + +// No Errors +const jsxWithJsxFragment = <>{test}; + +// Type '() => string' is not assignable to type 'ReactNode'. +const jsxWithReactFragment = {test}; + + +//// [index.js] +"use strict"; +/// +/// +const test = () => "asd"; +// No Errors +const jsxWithJsxFragment = React.createElement(React.Fragment, null, test); +// Type '() => string' is not assignable to type 'ReactNode'. +const jsxWithReactFragment = React.createElement(React.Fragment, null, test); diff --git a/tests/baselines/reference/jsxChildWrongFragment.symbols b/tests/baselines/reference/jsxChildWrongFragment.symbols new file mode 100644 index 0000000000000..4c57f23bcdc12 --- /dev/null +++ b/tests/baselines/reference/jsxChildWrongFragment.symbols @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/jsxChildWrongFragment.tsx] //// + +=== index.tsx === +/// +/// + +const test = () => "asd"; +>test : Symbol(test, Decl(index.tsx, 3, 5)) + +// No Errors +const jsxWithJsxFragment = <>{test}; +>jsxWithJsxFragment : Symbol(jsxWithJsxFragment, Decl(index.tsx, 6, 5)) +>test : Symbol(test, Decl(index.tsx, 3, 5)) + +// Type '() => string' is not assignable to type 'ReactNode'. +const jsxWithReactFragment = {test}; +>jsxWithReactFragment : Symbol(jsxWithReactFragment, Decl(index.tsx, 9, 5)) +>React.Fragment : Symbol(React.Fragment, Decl(react18.d.ts, 390, 9)) +>React : Symbol(React, Decl(react18.d.ts, 62, 15)) +>Fragment : Symbol(React.Fragment, Decl(react18.d.ts, 390, 9)) +>test : Symbol(test, Decl(index.tsx, 3, 5)) +>React.Fragment : Symbol(React.Fragment, Decl(react18.d.ts, 390, 9)) +>React : Symbol(React, Decl(react18.d.ts, 62, 15)) +>Fragment : Symbol(React.Fragment, Decl(react18.d.ts, 390, 9)) + diff --git a/tests/baselines/reference/jsxChildWrongFragment.types b/tests/baselines/reference/jsxChildWrongFragment.types new file mode 100644 index 0000000000000..2ec3d80766092 --- /dev/null +++ b/tests/baselines/reference/jsxChildWrongFragment.types @@ -0,0 +1,47 @@ +//// [tests/cases/compiler/jsxChildWrongFragment.tsx] //// + +=== Performance Stats === +Type Count: 1,000 + +=== index.tsx === +/// +/// + +const test = () => "asd"; +>test : () => string +> : ^^^^^^^^^^^^ +>() => "asd" : () => string +> : ^^^^^^^^^^^^ +>"asd" : "asd" +> : ^^^^^ + +// No Errors +const jsxWithJsxFragment = <>{test}; +>jsxWithJsxFragment : JSX.Element +> : ^^^^^^^^^^^ +><>{test} : JSX.Element +> : ^^^^^^^^^^^ +>test : () => string +> : ^^^^^^^^^^^^ + +// Type '() => string' is not assignable to type 'ReactNode'. +const jsxWithReactFragment = {test}; +>jsxWithReactFragment : JSX.Element +> : ^^^^^^^^^^^ +>{test} : JSX.Element +> : ^^^^^^^^^^^ +>React.Fragment : React.ExoticComponent<{ children?: React.ReactNode | undefined; }> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ +>React : typeof React +> : ^^^^^^^^^^^^ +>Fragment : React.ExoticComponent<{ children?: React.ReactNode | undefined; }> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ +>test : () => string +> : ^^^^^^^^^^^^ +>React.Fragment : React.ExoticComponent<{ children?: React.ReactNode | undefined; }> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ +>React : typeof React +> : ^^^^^^^^^^^^ +>Fragment : React.ExoticComponent<{ children?: React.ReactNode | undefined; }> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ + diff --git a/tests/cases/compiler/jsxChildWrongFragment.tsx b/tests/cases/compiler/jsxChildWrongFragment.tsx new file mode 100644 index 0000000000000..48c78cb70339c --- /dev/null +++ b/tests/cases/compiler/jsxChildWrongFragment.tsx @@ -0,0 +1,19 @@ +// @jsx: react +// @strict: true +// @target: ES2017 +// @module: ESNext +// @esModuleInterop: true +// @skipLibCheck: true + + +// @filename: index.tsx +/// +/// + +const test = () => "asd"; + +// No Errors +const jsxWithJsxFragment = <>{test}; + +// Type '() => string' is not assignable to type 'ReactNode'. +const jsxWithReactFragment = {test}; From 41b93dd2587090b497565003fe626e5b71ab950e Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Thu, 5 Sep 2024 00:15:49 -0700 Subject: [PATCH 02/16] fix bug in test case --- src/compiler/checker.ts | 314 +++++++++++------- src/compiler/types.ts | 6 +- src/compiler/utilities.ts | 2 + src/compiler/utilitiesPublic.ts | 8 + tests/baselines/reference/api/typescript.d.ts | 4 +- .../jsxChildWrongFragment.errors.txt | 9 +- .../cases/compiler/jsxChildWrongFragment.tsx | 1 - 7 files changed, 213 insertions(+), 131 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 52e6862110f53..97c864334931b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -631,7 +631,9 @@ import { isJsxAttribute, isJsxAttributeLike, isJsxAttributes, + isJsxCallLike, isJsxElement, + isJsxFragment, isJsxNamespacedName, isJsxOpeningElement, isJsxOpeningFragment, @@ -821,6 +823,7 @@ import { JsxAttributeName, JsxAttributes, JsxAttributeValue, + JsxCallLike, JsxChild, JsxClosingElement, JsxElement, @@ -32267,13 +32270,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return getContextualTypeForArgumentAtIndex(node, 0); } - function getEffectiveFirstArgumentForJsxSignature(signature: Signature, node: JsxOpeningLikeElement) { - return getJsxReferenceKind(node) !== JsxReferenceKind.Component + function getEffectiveFirstArgumentForJsxSignature(signature: Signature, node: JsxCallLike) { + return isJsxOpeningFragment(node) || getJsxReferenceKind(node) !== JsxReferenceKind.Component ? getJsxPropsTypeFromCallSignature(signature, node) : getJsxPropsTypeFromClassType(signature, node); } - function getJsxPropsTypeFromCallSignature(sig: Signature, context: JsxOpeningLikeElement) { + function getJsxPropsTypeFromCallSignature(sig: Signature, context: JsxCallLike) { let propsType = getTypeOfFirstParameterOfSignatureWithFallback(sig, unknownType); propsType = getJsxManagedAttributesFromLocatedAttributes(context, getJsxNamespaceAt(context), propsType); const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context); @@ -32308,7 +32311,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return isTypeAny(instanceType) ? instanceType : getTypeOfPropertyOfType(instanceType, forcedLookupLocation); } - function getStaticTypeOfReferencedJsxConstructor(context: JsxOpeningLikeElement) { + function getStaticTypeOfReferencedJsxConstructor(context: JsxCallLike) { + if (isJsxOpeningFragment(context)) return getJSXFragmentType(context); if (isJsxIntrinsicTagName(context.tagName)) { const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(context); const fakeSignature = createSignatureForJSXIntrinsic(context, result); @@ -32326,7 +32330,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return tagType; } - function getJsxManagedAttributesFromLocatedAttributes(context: JsxOpeningLikeElement, ns: Symbol, attributesType: Type) { + function getJsxManagedAttributesFromLocatedAttributes(context: JsxCallLike, ns: Symbol, attributesType: Type) { const managedSym = getJsxLibraryManagedAttributes(ns); if (managedSym) { const ctorType = getStaticTypeOfReferencedJsxConstructor(context); @@ -33109,9 +33113,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * @remarks Because this function calls getSpreadType, it needs to use the same checks as checkObjectLiteral, * which also calls getSpreadType. */ - function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, checkMode: CheckMode = CheckMode.Normal) { - const attributes = openingLikeElement.attributes; - const contextualType = getContextualType(attributes, ContextFlags.None); + function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxCallLike, checkMode: CheckMode = CheckMode.Normal) { const allAttributesTable = strictNullChecks ? createSymbolTable() : undefined; let attributesTable = createSymbolTable(); let spread: Type = emptyJsxObjectType; @@ -33120,72 +33122,86 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let explicitlySpecifyChildrenAttribute = false; let objectFlags: ObjectFlags = ObjectFlags.JsxAttributes; const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(openingLikeElement)); - - for (const attributeDecl of attributes.properties) { - const member = attributeDecl.symbol; - if (isJsxAttribute(attributeDecl)) { - const exprType = checkJsxAttribute(attributeDecl, checkMode); - objectFlags |= getObjectFlags(exprType) & ObjectFlags.PropagatingFlags; - - const attributeSymbol = createSymbol(SymbolFlags.Property | member.flags, member.escapedName); - attributeSymbol.declarations = member.declarations; - attributeSymbol.parent = member.parent; - if (member.valueDeclaration) { - attributeSymbol.valueDeclaration = member.valueDeclaration; - } - attributeSymbol.links.type = exprType; - attributeSymbol.links.target = member; - attributesTable.set(attributeSymbol.escapedName, attributeSymbol); - allAttributesTable?.set(attributeSymbol.escapedName, attributeSymbol); - if (getEscapedTextOfJsxAttributeName(attributeDecl.name) === jsxChildrenPropertyName) { - explicitlySpecifyChildrenAttribute = true; - } - if (contextualType) { - const prop = getPropertyOfType(contextualType, member.escapedName); - if (prop && prop.declarations && isDeprecatedSymbol(prop) && isIdentifier(attributeDecl.name)) { - addDeprecatedSuggestion(attributeDecl.name, prop.declarations, attributeDecl.name.escapedText as string); + + const isJsxOpenFragment = isJsxOpeningFragment(openingLikeElement); + + let attributesSymbol: Symbol | undefined; + let attributeParent: Node = openingLikeElement; + if (!isJsxOpenFragment) { + const attributes = openingLikeElement.attributes; + attributesSymbol = attributes.symbol; + attributeParent = attributes; + const contextualType = getContextualType(attributes, ContextFlags.None); + for (const attributeDecl of attributes.properties) { + const member = attributeDecl.symbol; + if (isJsxAttribute(attributeDecl)) { + const exprType = checkJsxAttribute(attributeDecl, checkMode); + objectFlags |= getObjectFlags(exprType) & ObjectFlags.PropagatingFlags; + + const attributeSymbol = createSymbol(SymbolFlags.Property | member.flags, member.escapedName); + attributeSymbol.declarations = member.declarations; + attributeSymbol.parent = member.parent; + if (member.valueDeclaration) { + attributeSymbol.valueDeclaration = member.valueDeclaration; + } + attributeSymbol.links.type = exprType; + attributeSymbol.links.target = member; + attributesTable.set(attributeSymbol.escapedName, attributeSymbol); + allAttributesTable?.set(attributeSymbol.escapedName, attributeSymbol); + if (getEscapedTextOfJsxAttributeName(attributeDecl.name) === jsxChildrenPropertyName) { + explicitlySpecifyChildrenAttribute = true; + } + if (contextualType) { + const prop = getPropertyOfType(contextualType, member.escapedName); + if (prop && prop.declarations && isDeprecatedSymbol(prop) && isIdentifier(attributeDecl.name)) { + addDeprecatedSuggestion(attributeDecl.name, prop.declarations, attributeDecl.name.escapedText as string); + } + } + if (contextualType && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) && isContextSensitive(attributeDecl)) { + const inferenceContext = getInferenceContext(attributes); + Debug.assert(inferenceContext); // In CheckMode.Inferential we should always have an inference context + const inferenceNode = (attributeDecl.initializer as JsxExpression).expression!; + addIntraExpressionInferenceSite(inferenceContext, inferenceNode, exprType); } } - if (contextualType && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) && isContextSensitive(attributeDecl)) { - const inferenceContext = getInferenceContext(attributes); - Debug.assert(inferenceContext); // In CheckMode.Inferential we should always have an inference context - const inferenceNode = (attributeDecl.initializer as JsxExpression).expression!; - addIntraExpressionInferenceSite(inferenceContext, inferenceNode, exprType); + else { + Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute); + if (attributesTable.size > 0) { + spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false); + attributesTable = createSymbolTable(); + } + const exprType = getReducedType(checkExpression(attributeDecl.expression, checkMode & CheckMode.Inferential)); + if (isTypeAny(exprType)) { + hasSpreadAnyType = true; + } + if (isValidSpreadType(exprType)) { + spread = getSpreadType(spread, exprType, attributes.symbol, objectFlags, /*readonly*/ false); + if (allAttributesTable) { + checkSpreadPropOverrides(exprType, allAttributesTable, attributeDecl); + } + } + else { + error(attributeDecl.expression, Diagnostics.Spread_types_may_only_be_created_from_object_types); + typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType; + } } } - else { - Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute); + + if (!hasSpreadAnyType) { if (attributesTable.size > 0) { spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false); - attributesTable = createSymbolTable(); - } - const exprType = getReducedType(checkExpression(attributeDecl.expression, checkMode & CheckMode.Inferential)); - if (isTypeAny(exprType)) { - hasSpreadAnyType = true; } - if (isValidSpreadType(exprType)) { - spread = getSpreadType(spread, exprType, attributes.symbol, objectFlags, /*readonly*/ false); - if (allAttributesTable) { - checkSpreadPropOverrides(exprType, allAttributesTable, attributeDecl); - } - } - else { - error(attributeDecl.expression, Diagnostics.Spread_types_may_only_be_created_from_object_types); - typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType; - } - } - } - - if (!hasSpreadAnyType) { - if (attributesTable.size > 0) { - spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false); } } // Handle children attribute - const parent = openingLikeElement.parent.kind === SyntaxKind.JsxElement ? openingLikeElement.parent as JsxElement : undefined; + const parent = openingLikeElement.parent; + // .kind === SyntaxKind.JsxElement ? openingLikeElement.parent as JsxElement + // : openingLikeElement.parent.kind === SyntaxKind.JsxFragment ? openingLikeElement.parent as JsxFragment : undefined; // We have to check that openingElement of the parent is the one we are visiting as this may not be true for selfClosingElement - if (parent && parent.openingElement === openingLikeElement && getSemanticJsxChildren(parent.children).length > 0) { + if ((isJsxElement(parent) && parent.openingElement === openingLikeElement || isJsxFragment(parent) && parent.openingFragment === openingLikeElement) && + getSemanticJsxChildren(parent.children).length > 0 + ) { const childrenTypes: Type[] = checkJsxChildren(parent, checkMode); if (!hasSpreadAnyType && jsxChildrenPropertyName && jsxChildrenPropertyName !== "") { @@ -33193,10 +33209,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // This is because children element will overwrite the value from attributes. // Note: we will not warn "children" attribute overwritten if "children" attribute is specified in object spread. if (explicitlySpecifyChildrenAttribute) { - error(attributes, Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, unescapeLeadingUnderscores(jsxChildrenPropertyName)); + error(attributeParent, Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, unescapeLeadingUnderscores(jsxChildrenPropertyName)); } - const contextualType = getApparentTypeOfContextualType(openingLikeElement.attributes, /*contextFlags*/ undefined); + const contextualType = isJsxOpeningElement(openingLikeElement) ? getApparentTypeOfContextualType(openingLikeElement.attributes, /*contextFlags*/ undefined) : undefined; const childrenContextualType = contextualType && getTypeOfPropertyOfContextualType(contextualType, jsxChildrenPropertyName); // If there are children in the body of JSX element, create dummy attribute "children" with the union of children types so that it will pass the attribute checking process const childrenPropSymbol = createSymbol(SymbolFlags.Property, jsxChildrenPropertyName); @@ -33205,11 +33221,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { createArrayType(getUnionType(childrenTypes)); // Fake up a property declaration for the children childrenPropSymbol.valueDeclaration = factory.createPropertySignature(/*modifiers*/ undefined, unescapeLeadingUnderscores(jsxChildrenPropertyName), /*questionToken*/ undefined, /*type*/ undefined); - setParent(childrenPropSymbol.valueDeclaration, attributes); + setParent(childrenPropSymbol.valueDeclaration, attributeParent); childrenPropSymbol.valueDeclaration.symbol = childrenPropSymbol; const childPropMap = createSymbolTable(); childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol); - spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, emptyArray), attributes.symbol, objectFlags, /*readonly*/ false); + spread = getSpreadType(spread, createAnonymousType(attributesSymbol, childPropMap, emptyArray, emptyArray, emptyArray), attributesSymbol, objectFlags, /*readonly*/ false); } } @@ -33228,7 +33244,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { */ function createJsxAttributesType() { objectFlags |= ObjectFlags.FreshLiteral; - const result = createAnonymousType(attributes.symbol, attributesTable, emptyArray, emptyArray, emptyArray); + const result = createAnonymousType(attributesSymbol, attributesTable, emptyArray, emptyArray, emptyArray); result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; return result; } @@ -33443,7 +33459,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer, jsxNamespace); } - function getUninstantiatedJsxSignaturesOfType(elementType: Type, caller: JsxOpeningLikeElement): readonly Signature[] { + function getUninstantiatedJsxSignaturesOfType(elementType: Type, caller: JsxCallLike): readonly Signature[] { if (elementType.flags & TypeFlags.String) { return [anySignature]; } @@ -33623,11 +33639,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { markJsxAliasReferenced(node); + const sig = getResolvedSignature(node); + checkDeprecatedSignature(sig, node); + if (isNodeOpeningLikeElement) { const jsxOpeningLikeNode = node; - const sig = getResolvedSignature(jsxOpeningLikeNode); - checkDeprecatedSignature(sig, node); - const elementTypeConstraint = getJsxElementTypeTypeAt(jsxOpeningLikeNode); if (elementTypeConstraint !== undefined) { const tagName = jsxOpeningLikeNode.tagName; @@ -34962,6 +34978,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function hasCorrectArity(node: CallLikeExpression, args: readonly Expression[], signature: Signature, signatureHelpTrailingComma = false) { + if (isJsxOpeningFragment(node)) return true; + let argCount: number; let callIsIncomplete = false; // In incomplete call we want to be lenient when we have too few arguments let effectiveParameterCount = getParameterCount(signature); @@ -35318,8 +35336,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * @param signature a candidate signature we are trying whether it is a call signature * @param relation a relationship to check parameter and argument type */ - function checkApplicableSignatureForJsxOpeningLikeElement( - node: JsxOpeningLikeElement, + function checkApplicableSignatureForJsxCallLikeElement( + node: JsxCallLike, signature: Signature, relation: Map, checkMode: CheckMode, @@ -35331,14 +35349,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props, // can be specified by users through attributes property. const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node); - const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*inferenceContext*/ undefined, checkMode); + const attributesType = isJsxOpeningFragment(node) ? createJsxAttributesTypeFromAttributesProperty(node) : checkExpressionWithContextualType(node.attributes, paramType, /*inferenceContext*/ undefined, checkMode); const checkAttributesType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(attributesType) : attributesType; return checkTagNameDoesNotExpectTooManyArguments() && checkTypeRelatedToAndOptionallyElaborate( checkAttributesType, paramType, relation, - reportErrors ? node.tagName : undefined, - node.attributes, + reportErrors ? isJsxOpeningFragment(node) ? node : node.tagName : undefined, + isJsxOpeningFragment(node) ? undefined : node.attributes, /*headMessage*/ undefined, containingMessageChain, errorOutputContainer, @@ -35406,10 +35424,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (reportErrors) { - 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); - const tagNameDeclaration = getSymbolAtLocation(node.tagName)?.valueDeclaration; + const errorNode = isJsxOpeningFragment(node) ? node : node.tagName; + const errorEntityName = isJsxOpeningFragment(node) ? 'Fragment' : entityNameToString(node.tagName); + const diag = createDiagnosticForNode(errorNode, Diagnostics.Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3, errorEntityName, absoluteMinArgCount, entityNameToString(factory), maxParamCount); + const tagNameDeclaration = isJsxOpeningFragment(node) ? getJSXFragmentType(node).symbol.valueDeclaration : getSymbolAtLocation(node.tagName)?.valueDeclaration; if (tagNameDeclaration) { - addRelatedInfo(diag, createDiagnosticForNode(tagNameDeclaration, Diagnostics._0_is_declared_here, entityNameToString(node.tagName))); + addRelatedInfo(diag, createDiagnosticForNode(tagNameDeclaration, Diagnostics._0_is_declared_here, errorEntityName)); } if (errorOutputContainer && errorOutputContainer.skipLogging) { (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag); @@ -35438,8 +35458,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { inferenceContext: InferenceContext | undefined, ): readonly Diagnostic[] | undefined { const errorOutputContainer: { errors?: Diagnostic[]; skipLogging?: boolean; } = { errors: undefined, skipLogging: true }; - if (isJsxOpeningLikeElement(node)) { - if (!checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors, containingMessageChain, errorOutputContainer)) { + if (isJsxCallLike(node)) { + if (!checkApplicableSignatureForJsxCallLikeElement(node, signature, relation, checkMode, reportErrors, containingMessageChain, errorOutputContainer)) { Debug.assert(!reportErrors || !!errorOutputContainer.errors, "jsx should have errors when reporting errors"); return errorOutputContainer.errors || emptyArray; } @@ -35542,6 +35562,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * Returns the effective arguments for an expression that works like a function invocation. */ function getEffectiveCallArguments(node: CallLikeExpression): readonly Expression[] { + if (isJsxOpeningFragment(node)) return emptyArray; + if (node.kind === SyntaxKind.TaggedTemplateExpression) { const template = node.template; const args: Expression[] = [createSyntheticExpression(template, getGlobalTemplateStringsArrayType())]; @@ -35820,12 +35842,42 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression; const isDecorator = node.kind === SyntaxKind.Decorator; const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node); + const isJsxOpenFragment = isJsxOpeningFragment(node); const isInstanceof = node.kind === SyntaxKind.BinaryExpression; const reportErrors = !isInferencePartiallyBlocked && !candidatesOutArray; - let typeArguments: NodeArray | undefined; + // The following variables are captured and modified by calls to chooseOverload. + // If overload resolution or type argument inference fails, we want to report the + // best error possible. The best error is one which says that an argument was not + // assignable to a parameter. This implies that everything else about the overload + // was fine. So if there is any overload that is only incorrect because of an + // argument, we will report an error on that one. + // + // function foo(s: string): void; + // function foo(n: number): void; // Report argument error on this overload + // function foo(): void; + // foo(true); + // + // If none of the overloads even made it that far, there are two possibilities. + // There was a problem with type arguments for some overload, in which case + // report an error on that. Or none of the overloads even had correct arity, + // in which case give an arity error. + // + // function foo(x: T): void; // Report type argument error + // function foo(): void; + // foo(0); + // + let candidatesForArgumentError: Signature[] | undefined; + let candidateForArgumentArityError: Signature | undefined; + let candidateForTypeArgumentError: Signature | undefined; + let result: Signature | undefined; + let argCheckMode = CheckMode.Normal; - if (!isDecorator && !isInstanceof && !isSuperCall(node)) { + // let args : readonly Expression[]; + let candidates: Signature[] = []; + let typeArguments: NodeArray | undefined; + // if (!isJsxOpenFragment) { + if (!isDecorator && !isInstanceof && !isSuperCall(node) && !isJsxOpenFragment) { typeArguments = (node as CallExpression).typeArguments; // We already perform checking on the type arguments on the class declaration itself. @@ -35834,11 +35886,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - const candidates = candidatesOutArray || []; + candidates = candidatesOutArray || []; // reorderCandidates fills up the candidates array directly reorderCandidates(signatures, candidates, callChainFlags); - Debug.assert(candidates.length, "Revert #54442 and add a testcase with whatever triggered this"); - + if (!isJsxOpenFragment) { + Debug.assert(candidates.length, "Revert #54442 and add a testcase with whatever triggered this"); + } const args = getEffectiveCallArguments(node); // The excludeArgument array contains true for each context sensitive argument (an argument @@ -35854,33 +35907,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // For a decorator, no arguments are susceptible to contextual typing due to the fact // decorators are applied to a declaration by the emitter, and not to an expression. const isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters; - let argCheckMode = !isDecorator && !isSingleNonGenericCandidate && some(args, isContextSensitive) ? CheckMode.SkipContextSensitive : CheckMode.Normal; - - // The following variables are captured and modified by calls to chooseOverload. - // If overload resolution or type argument inference fails, we want to report the - // best error possible. The best error is one which says that an argument was not - // assignable to a parameter. This implies that everything else about the overload - // was fine. So if there is any overload that is only incorrect because of an - // argument, we will report an error on that one. - // - // function foo(s: string): void; - // function foo(n: number): void; // Report argument error on this overload - // function foo(): void; - // foo(true); - // - // If none of the overloads even made it that far, there are two possibilities. - // There was a problem with type arguments for some overload, in which case - // report an error on that. Or none of the overloads even had correct arity, - // in which case give an arity error. - // - // function foo(x: T): void; // Report type argument error - // function foo(): void; - // foo(0); - // - let candidatesForArgumentError: Signature[] | undefined; - let candidateForArgumentArityError: Signature | undefined; - let candidateForTypeArgumentError: Signature | undefined; - let result: Signature | undefined; + if (!isDecorator && !isSingleNonGenericCandidate && some(args, isContextSensitive)) { + argCheckMode = CheckMode.SkipContextSensitive; + } // If we are in signature help, a trailing comma indicates that we intend to provide another argument, // so we will only accept overloads with arity at least 1 higher than the current number of provided arguments. @@ -36005,7 +36034,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else if (candidateForTypeArgumentError) { checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression | JsxOpeningLikeElement).typeArguments!, /*reportErrors*/ true, headMessage); } - else { + else if (!isJsxOpenFragment) { const signaturesWithCorrectTypeArgumentArity = filter(signatures, s => hasCorrectTypeArgumentArity(s, typeArguments)); if (signaturesWithCorrectTypeArgumentArity.length === 0) { diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments!, headMessage)); @@ -36747,7 +36776,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return resolveCall(node, callSignatures, candidatesOutArray, checkMode, SignatureFlags.None, headMessage); } - function createSignatureForJSXIntrinsic(node: JsxOpeningLikeElement, result: Type): Signature { + function createSignatureForJSXIntrinsic(node: JsxCallLike, result: Type): Signature { const namespace = getJsxNamespaceAt(node); const exports = namespace && getExportsOfSymbol(namespace); // We fake up a SFC signature for each intrinsic, however a more specific per-element signature drawn from the JSX declaration @@ -36769,23 +36798,44 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { ); } - function resolveJsxOpeningLikeElement(node: JsxOpeningLikeElement, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature { - if (isJsxIntrinsicTagName(node.tagName)) { - const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node); - const fakeSignature = createSignatureForJSXIntrinsic(node, result); - checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*inferenceContext*/ undefined, CheckMode.Normal), result, node.tagName, node.attributes); - if (length(node.typeArguments)) { - forEach(node.typeArguments, checkSourceElement); - diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), node.typeArguments!, Diagnostics.Expected_0_type_arguments_but_got_1, 0, length(node.typeArguments))); + function getJSXFragmentType(node: Node): Type { + // This function + const jsxFactoryRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined; + const jsxFactorySymbol = resolveName(node, getJsxNamespace(node), SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true); + // Debug.assert(jsxFactorySymbol); + + const reactExports = jsxFactorySymbol && getExportsOfSymbol(resolveAlias(jsxFactorySymbol)); + const typeSymbol = reactExports && getSymbol(reactExports, ReactNames.Fragment, SymbolFlags.BlockScopedVariable); + // Debug.assert(typeSymbol); + + const type = typeSymbol && getTypeOfSymbol(typeSymbol); + Debug.assert(type); + return type; + } + + function resolveJsxOpeningLikeElement(node: JsxCallLike, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature { + const isJsxOpenFragment = isJsxOpeningFragment(node); + let exprTypes: Type; + if (!isJsxOpenFragment) { + if (isJsxIntrinsicTagName(node.tagName)) { + const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node); + const fakeSignature = createSignatureForJSXIntrinsic(node, result); + checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*inferenceContext*/ undefined, CheckMode.Normal), result, node.tagName, node.attributes); + if (length(node.typeArguments)) { + forEach(node.typeArguments, checkSourceElement); + diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), node.typeArguments!, Diagnostics.Expected_0_type_arguments_but_got_1, 0, length(node.typeArguments))); + } + return fakeSignature; } - return fakeSignature; + exprTypes = checkExpression(node.tagName); + } + else { + exprTypes = getJSXFragmentType(node); } - const exprTypes = checkExpression(node.tagName); const apparentType = getApparentType(exprTypes); if (isErrorType(apparentType)) { return resolveErrorCall(node); } - const signatures = getUninstantiatedJsxSignaturesOfType(exprTypes, node); if (isUntypedFunctionCall(exprTypes, apparentType, signatures.length, /*constructSignatures*/ 0)) { return resolveUntypedCall(node); @@ -36793,7 +36843,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (signatures.length === 0) { // We found no signatures at all, which is an error - error(node.tagName, Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, getTextOfNode(node.tagName)); + if (isJsxOpenFragment) { + error(node, Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, getTextOfNode(node)); + } + else { + error(node.tagName, Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, getTextOfNode(node.tagName)); + } return resolveErrorCall(node); } @@ -36855,6 +36910,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return resolveTaggedTemplateExpression(node, candidatesOutArray, checkMode); case SyntaxKind.Decorator: return resolveDecorator(node, candidatesOutArray, checkMode); + case SyntaxKind.JsxOpeningFragment: case SyntaxKind.JsxOpeningElement: case SyntaxKind.JsxSelfClosingElement: return resolveJsxOpeningLikeElement(node, candidatesOutArray, checkMode); @@ -52697,6 +52753,10 @@ namespace JsxNames { export const LibraryManagedAttributes = "LibraryManagedAttributes" as __String; } +namespace ReactNames { + export const Fragment = "Fragment" as __String; +} + function getIterationTypesKeyFromIterationTypeKind(typeKind: IterationTypeKind) { switch (typeKind) { case IterationTypeKind.Yield: diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 7a7652eece24d..e788f8268a76d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3126,7 +3126,7 @@ export type CallLikeExpression = | NewExpression | TaggedTemplateExpression | Decorator - | JsxOpeningLikeElement + | JsxCallLike | InstanceofExpression; export interface AsExpression extends Expression { @@ -3187,6 +3187,10 @@ export type JsxOpeningLikeElement = | JsxSelfClosingElement | JsxOpeningElement; +export type JsxCallLike = + | JsxOpeningLikeElement + | JsxOpeningFragment; + export type JsxAttributeLike = | JsxAttribute | JsxSpreadAttribute; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 673c0b38c156d..86c9ff0c8509e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3315,6 +3315,8 @@ export function getInvokedExpression(node: CallLikeExpression): Expression | Jsx return node.tagName; case SyntaxKind.BinaryExpression: return node.right; + case SyntaxKind.JsxOpeningFragment: + return node; default: return node.expression; } diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 8d15a85dad1c4..0e0e83455ad9f 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -204,6 +204,7 @@ import { JSDocTypedefTag, JSDocTypeTag, JsxAttributeLike, + JsxCallLike, JsxChild, JsxExpression, JsxOpeningLikeElement, @@ -2469,6 +2470,13 @@ export function isJsxOpeningLikeElement(node: Node): node is JsxOpeningLikeEleme || kind === SyntaxKind.JsxSelfClosingElement; } +export function isJsxCallLike(node: Node): node is JsxCallLike { + const kind = node.kind; + return kind === SyntaxKind.JsxOpeningElement + || kind === SyntaxKind.JsxSelfClosingElement + || kind === SyntaxKind.JsxOpeningFragment; +} + // Clauses export function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 5122694b16787..5a0f80b3f6a84 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5099,7 +5099,7 @@ declare namespace ts { interface InstanceofExpression extends BinaryExpression { readonly operatorToken: Token; } - type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement | InstanceofExpression; + type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxCallLike | InstanceofExpression; interface AsExpression extends Expression { readonly kind: SyntaxKind.AsExpression; readonly expression: Expression; @@ -5135,6 +5135,7 @@ declare namespace ts { readonly closingElement: JsxClosingElement; } type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement; + type JsxCallLike = JsxOpeningLikeElement | JsxOpeningFragment; type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute; type JsxAttributeName = Identifier | JsxNamespacedName; type JsxTagNameExpression = Identifier | ThisExpression | JsxTagNamePropertyAccess | JsxNamespacedName; @@ -8747,6 +8748,7 @@ declare namespace ts { function isJsxAttributeLike(node: Node): node is JsxAttributeLike; function isStringLiteralOrJsxExpression(node: Node): node is StringLiteral | JsxExpression; function isJsxOpeningLikeElement(node: Node): node is JsxOpeningLikeElement; + function isJsxCallLike(node: Node): node is JsxCallLike; function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause; /** True if node is of a kind that may contain comment text. */ function isJSDocCommentContainingNode(node: Node): boolean; diff --git a/tests/baselines/reference/jsxChildWrongFragment.errors.txt b/tests/baselines/reference/jsxChildWrongFragment.errors.txt index 55cb3372248a4..107255867afcf 100644 --- a/tests/baselines/reference/jsxChildWrongFragment.errors.txt +++ b/tests/baselines/reference/jsxChildWrongFragment.errors.txt @@ -1,7 +1,10 @@ +index.tsx(7,28): error TS2322: Type '{ children: () => string; }' is not assignable to type '{ children?: ReactNode; }'. + Types of property 'children' are incompatible. + Type '() => string' is not assignable to type 'ReactNode'. index.tsx(10,47): error TS2322: Type '() => string' is not assignable to type 'ReactNode'. -==== index.tsx (1 errors) ==== +==== index.tsx (2 errors) ==== /// /// @@ -9,6 +12,10 @@ index.tsx(10,47): error TS2322: Type '() => string' is not assignable to type 'R // No Errors const jsxWithJsxFragment = <>{test}; + ~~ +!!! error TS2322: Type '{ children: () => string; }' is not assignable to type '{ children?: ReactNode; }'. +!!! error TS2322: Types of property 'children' are incompatible. +!!! error TS2322: Type '() => string' is not assignable to type 'ReactNode'. // Type '() => string' is not assignable to type 'ReactNode'. const jsxWithReactFragment = {test}; diff --git a/tests/cases/compiler/jsxChildWrongFragment.tsx b/tests/cases/compiler/jsxChildWrongFragment.tsx index 48c78cb70339c..67c4d78dc971b 100644 --- a/tests/cases/compiler/jsxChildWrongFragment.tsx +++ b/tests/cases/compiler/jsxChildWrongFragment.tsx @@ -5,7 +5,6 @@ // @esModuleInterop: true // @skipLibCheck: true - // @filename: index.tsx /// /// From 423ee81f870328e2e895a094f6c16cc7df320702 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Tue, 10 Sep 2024 12:17:52 -0700 Subject: [PATCH 03/16] fix implicit import --- src/compiler/checker.ts | 35 ++++++++----- .../inlineJsxAndJsxFragPragma.errors.txt | 15 ++++-- ...gPragmaOverridesCompilerOptions.errors.txt | 49 +++++++++++++++++++ ...sxFragPragmaOverridesCompilerOptions.types | 24 ++++++--- ...actoryAndJsxFragmentFactoryNull.errors.txt | 16 ++++++ .../jsxFactoryAndJsxFragmentFactoryNull.types | 19 ++++--- 6 files changed, 128 insertions(+), 30 deletions(-) create mode 100644 tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt create mode 100644 tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 97c864334931b..c9018ee7bf0fa 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33122,9 +33122,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let explicitlySpecifyChildrenAttribute = false; let objectFlags: ObjectFlags = ObjectFlags.JsxAttributes; const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(openingLikeElement)); - + const isJsxOpenFragment = isJsxOpeningFragment(openingLikeElement); - + let attributesSymbol: Symbol | undefined; let attributeParent: Node = openingLikeElement; if (!isJsxOpenFragment) { @@ -33196,10 +33196,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Handle children attribute const parent = openingLikeElement.parent; - // .kind === SyntaxKind.JsxElement ? openingLikeElement.parent as JsxElement - // : openingLikeElement.parent.kind === SyntaxKind.JsxFragment ? openingLikeElement.parent as JsxFragment : undefined; // We have to check that openingElement of the parent is the one we are visiting as this may not be true for selfClosingElement - if ((isJsxElement(parent) && parent.openingElement === openingLikeElement || isJsxFragment(parent) && parent.openingFragment === openingLikeElement) && + if ( + (isJsxElement(parent) && parent.openingElement === openingLikeElement || isJsxFragment(parent) && parent.openingFragment === openingLikeElement) && getSemanticJsxChildren(parent.children).length > 0 ) { const childrenTypes: Type[] = checkJsxChildren(parent, checkMode); @@ -35425,7 +35424,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (reportErrors) { const errorNode = isJsxOpeningFragment(node) ? node : node.tagName; - const errorEntityName = isJsxOpeningFragment(node) ? 'Fragment' : entityNameToString(node.tagName); + const errorEntityName = isJsxOpeningFragment(node) ? "Fragment" : entityNameToString(node.tagName); const diag = createDiagnosticForNode(errorNode, Diagnostics.Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3, errorEntityName, absoluteMinArgCount, entityNameToString(factory), maxParamCount); const tagNameDeclaration = isJsxOpeningFragment(node) ? getJSXFragmentType(node).symbol.valueDeclaration : getSymbolAtLocation(node.tagName)?.valueDeclaration; if (tagNameDeclaration) { @@ -36798,18 +36797,28 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { ); } - function getJSXFragmentType(node: Node): Type { - // This function + function getJSXFragmentType(node: JsxOpeningFragment): Type { + // An opening fragment is required in order for `getJsxNamespace` to give the fragment factory + const jsxFragmentFactoryName = getJsxNamespace(node); const jsxFactoryRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined; - const jsxFactorySymbol = resolveName(node, getJsxNamespace(node), SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true); - // Debug.assert(jsxFactorySymbol); + const jsxFactorySymbol = getJsxNamespaceContainerForImplicitImport(node) ?? + resolveName(node, jsxFragmentFactoryName, SymbolFlags.Value, /*nameNotFoundMessage*/ jsxFactoryRefErr, /*isUse*/ true); + if (jsxFactorySymbol === undefined) { + return errorType; + } + if (jsxFactorySymbol.escapedName === ReactNames.Fragment) { + return getTypeOfSymbol(jsxFactorySymbol); + } + + const resolvedAlias = (jsxFactorySymbol.flags & SymbolFlags.Alias) === 0 ? jsxFactorySymbol : resolveAlias(jsxFactorySymbol); - const reactExports = jsxFactorySymbol && getExportsOfSymbol(resolveAlias(jsxFactorySymbol)); + const reactExports = jsxFactorySymbol && getExportsOfSymbol(resolvedAlias); const typeSymbol = reactExports && getSymbol(reactExports, ReactNames.Fragment, SymbolFlags.BlockScopedVariable); - // Debug.assert(typeSymbol); const type = typeSymbol && getTypeOfSymbol(typeSymbol); - Debug.assert(type); + if (type === undefined) { + return errorType; + } return type; } diff --git a/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt b/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt index f1f2b35d5d6f0..03bae5708da87 100644 --- a/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt +++ b/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt @@ -1,6 +1,9 @@ preacty-no-fragment.tsx(5,12): error TS6133: 'Fragment' is declared but its value is never read. preacty-only-fragment-no-jsx.tsx(6,1): error TS2304: Cannot find name 'h'. snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2304: Cannot find name 'jsx'. +snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2304: Cannot find name 'null'. +snabbdomy-only-fragment.tsx(4,1): error TS2304: Cannot find name 'null'. +snabbdomy.tsx(4,1): error TS2304: Cannot find name 'null'. ==== renderer.d.ts (0 errors) ==== @@ -23,11 +26,13 @@ snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2304: Cannot find name 'jsx'. import {h, Fragment} from "./renderer"; <>
-==== snabbdomy.tsx (0 errors) ==== +==== snabbdomy.tsx (1 errors) ==== /* @jsx jsx */ /* @jsxfrag null */ import {jsx} from "./renderer"; <> + ~~ +!!! error TS2304: Cannot find name 'null'. ==== preacty-only-fragment.tsx (0 errors) ==== /** @@ -37,11 +42,13 @@ snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2304: Cannot find name 'jsx'. import {h, Fragment} from "./renderer"; <> -==== snabbdomy-only-fragment.tsx (0 errors) ==== +==== snabbdomy-only-fragment.tsx (1 errors) ==== /* @jsx jsx */ /* @jsxfrag null */ import {jsx} from "./renderer"; <> + ~~ +!!! error TS2304: Cannot find name 'null'. ==== preacty-only-fragment-no-jsx.tsx (1 errors) ==== /** @@ -53,13 +60,15 @@ snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2304: Cannot find name 'jsx'. ~~ !!! error TS2304: Cannot find name 'h'. -==== snabbdomy-only-fragment-no-jsx.tsx (1 errors) ==== +==== snabbdomy-only-fragment-no-jsx.tsx (2 errors) ==== /* @jsx jsx */ /* @jsxfrag null */ import {} from "./renderer"; <> ~~ !!! error TS2304: Cannot find name 'jsx'. + ~~ +!!! error TS2304: Cannot find name 'null'. ==== preacty-no-fragment.tsx (1 errors) ==== /** diff --git a/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt b/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt new file mode 100644 index 0000000000000..a9e365970bc41 --- /dev/null +++ b/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt @@ -0,0 +1,49 @@ +snabbdomy.tsx(6,1): error TS2304: Cannot find name 'null'. + + +==== react.d.ts (0 errors) ==== + declare global { + namespace JSX { + interface IntrinsicElements { + [e: string]: any; + } + } + } + export function createElement(): void; + export function Fragment(): void; + +==== preact.d.ts (0 errors) ==== + export function h(): void; + export function Frag(): void; + +==== snabbdom.d.ts (0 errors) ==== + export function h(): void; + +==== reacty.tsx (0 errors) ==== + import {createElement, Fragment} from "./react"; + <> + +==== preacty.tsx (0 errors) ==== + /** + * @jsx h + * @jsxFrag Frag + */ + import {h, Frag} from "./preact"; + <>
+ +==== snabbdomy.tsx (1 errors) ==== + /** + * @jsx h + * @jsxfrag null + */ + import {h} from "./snabbdom"; + <>
+ ~~ +!!! error TS2304: Cannot find name 'null'. + +==== mix-n-match.tsx (0 errors) ==== + /* @jsx h */ + /* @jsxFrag Fragment */ + import {h} from "./preact"; + import {Fragment} from "./react"; + <> \ No newline at end of file diff --git a/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.types b/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.types index 8fb864cf2a86e..7920f66d89cee 100644 --- a/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.types +++ b/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.types @@ -43,8 +43,10 @@ import {createElement, Fragment} from "./react"; > : ^^^^^^ <> -><> : error -> : error +><> : any +> : ^^^ +> : any +> : ^^^ >span : any > : ^^^ >span : any @@ -62,8 +64,10 @@ import {h, Frag} from "./preact"; > : ^^^^^^ <>
-><>
: error ->
: error +><>
: any +> : ^^^ +>
: any +> : ^^^ >div : any > : ^^^ >div : any @@ -79,8 +83,10 @@ import {h} from "./snabbdom"; > : ^^^^^^ <>
-><>
: error ->
: error +><>
: any +> : ^^^ +>
: any +> : ^^^ >div : any > : ^^^ >div : any @@ -98,8 +104,10 @@ import {Fragment} from "./react"; > : ^^^^^^ <> -><> : error -> : error +><> : any +> : ^^^ +> : any +> : ^^^ >span : any > : ^^^ >span : any diff --git a/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt new file mode 100644 index 0000000000000..227df27f1649e --- /dev/null +++ b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt @@ -0,0 +1,16 @@ +jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS2304: Cannot find name 'null'. +jsxFactoryAndJsxFragmentFactoryNull.tsx(4,1): error TS2304: Cannot find name 'null'. +jsxFactoryAndJsxFragmentFactoryNull.tsx(4,17): error TS2304: Cannot find name 'null'. + + +==== jsxFactoryAndJsxFragmentFactoryNull.tsx (3 errors) ==== + declare var h: any; + + <>; + ~~ +!!! error TS2304: Cannot find name 'null'. + <>1<>2.12.2; + ~~ +!!! error TS2304: Cannot find name 'null'. + ~~ +!!! error TS2304: Cannot find name 'null'. \ No newline at end of file diff --git a/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.types b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.types index 2517020c3b2fd..5c9d13f33a5ab 100644 --- a/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.types +++ b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.types @@ -3,24 +3,31 @@ === jsxFactoryAndJsxFragmentFactoryNull.tsx === declare var h: any; >h : any +> : ^^^ <>; -><> : error +><> : any +> : ^^^ <>1<>2.12.2; -><>1<>2.12.2 : error ->1 : error +><>1<>2.12.2 : any +> : ^^^ +>1 : any +> : ^^^ >span : any > : ^^^ >span : any > : ^^^ -><>2.12.2 : error ->2.1 : error +><>2.12.2 : any +> : ^^^ +>2.1 : any +> : ^^^ >span : any > : ^^^ >span : any > : ^^^ ->2.2 : error +>2.2 : any +> : ^^^ >span : any > : ^^^ >span : any From 48187e8c64f5cbefb18f5c7ff62cc48985a50457 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Fri, 13 Sep 2024 11:54:14 -0700 Subject: [PATCH 04/16] clean up tests and comments --- src/compiler/checker.ts | 2 -- .../jsxChildWrongFragment.errors.txt | 19 +++++++++++++------ .../reference/jsxChildWrongFragment.js | 11 ++++++----- .../reference/jsxChildWrongFragment.symbols | 9 ++++++--- .../reference/jsxChildWrongFragment.types | 13 +++++++++++-- .../cases/compiler/jsxChildWrongFragment.tsx | 6 +++--- 6 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c9018ee7bf0fa..c29768a6cd223 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -35872,10 +35872,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let result: Signature | undefined; let argCheckMode = CheckMode.Normal; - // let args : readonly Expression[]; let candidates: Signature[] = []; let typeArguments: NodeArray | undefined; - // if (!isJsxOpenFragment) { if (!isDecorator && !isInstanceof && !isSuperCall(node) && !isJsxOpenFragment) { typeArguments = (node as CallExpression).typeArguments; diff --git a/tests/baselines/reference/jsxChildWrongFragment.errors.txt b/tests/baselines/reference/jsxChildWrongFragment.errors.txt index 107255867afcf..5af6adf1cc929 100644 --- a/tests/baselines/reference/jsxChildWrongFragment.errors.txt +++ b/tests/baselines/reference/jsxChildWrongFragment.errors.txt @@ -1,25 +1,32 @@ index.tsx(7,28): error TS2322: Type '{ children: () => string; }' is not assignable to type '{ children?: ReactNode; }'. Types of property 'children' are incompatible. Type '() => string' is not assignable to type 'ReactNode'. -index.tsx(10,47): error TS2322: Type '() => string' is not assignable to type 'ReactNode'. +index.tsx(8,47): error TS2322: Type '() => string' is not assignable to type 'ReactNode'. +index.tsx(10,29): error TS2322: Type '{ children: () => string; }' is not assignable to type '{ children?: ReactNode; }'. + Types of property 'children' are incompatible. + Type '() => string' is not assignable to type 'ReactNode'. -==== index.tsx (2 errors) ==== +==== index.tsx (3 errors) ==== /// /// const test = () => "asd"; - // No Errors + // these two should error in the same way const jsxWithJsxFragment = <>{test}; ~~ !!! error TS2322: Type '{ children: () => string; }' is not assignable to type '{ children?: ReactNode; }'. !!! error TS2322: Types of property 'children' are incompatible. !!! error TS2322: Type '() => string' is not assignable to type 'ReactNode'. - - // Type '() => string' is not assignable to type 'ReactNode'. const jsxWithReactFragment = {test}; ~~~~ !!! error TS2322: Type '() => string' is not assignable to type 'ReactNode'. -!!! related TS6212 index.tsx:10:47: Did you mean to call this expression? +!!! related TS6212 index.tsx:8:47: Did you mean to call this expression? + + const jsxNestedFragment = <><>{test}; + ~~ +!!! error TS2322: Type '{ children: () => string; }' is not assignable to type '{ children?: ReactNode; }'. +!!! error TS2322: Types of property 'children' are incompatible. +!!! error TS2322: Type '() => string' is not assignable to type 'ReactNode'. \ No newline at end of file diff --git a/tests/baselines/reference/jsxChildWrongFragment.js b/tests/baselines/reference/jsxChildWrongFragment.js index dd3c3c5731a8b..79b221236c4f7 100644 --- a/tests/baselines/reference/jsxChildWrongFragment.js +++ b/tests/baselines/reference/jsxChildWrongFragment.js @@ -6,11 +6,11 @@ const test = () => "asd"; -// No Errors +// these two should error in the same way const jsxWithJsxFragment = <>{test}; - -// Type '() => string' is not assignable to type 'ReactNode'. const jsxWithReactFragment = {test}; + +const jsxNestedFragment = <><>{test}; //// [index.js] @@ -18,7 +18,8 @@ const jsxWithReactFragment = {test}; /// /// const test = () => "asd"; -// No Errors +// these two should error in the same way const jsxWithJsxFragment = React.createElement(React.Fragment, null, test); -// Type '() => string' is not assignable to type 'ReactNode'. const jsxWithReactFragment = React.createElement(React.Fragment, null, test); +const jsxNestedFragment = React.createElement(React.Fragment, null, + React.createElement(React.Fragment, null, test)); diff --git a/tests/baselines/reference/jsxChildWrongFragment.symbols b/tests/baselines/reference/jsxChildWrongFragment.symbols index 4c57f23bcdc12..9322c9aa77f74 100644 --- a/tests/baselines/reference/jsxChildWrongFragment.symbols +++ b/tests/baselines/reference/jsxChildWrongFragment.symbols @@ -7,14 +7,13 @@ const test = () => "asd"; >test : Symbol(test, Decl(index.tsx, 3, 5)) -// No Errors +// these two should error in the same way const jsxWithJsxFragment = <>{test}; >jsxWithJsxFragment : Symbol(jsxWithJsxFragment, Decl(index.tsx, 6, 5)) >test : Symbol(test, Decl(index.tsx, 3, 5)) -// Type '() => string' is not assignable to type 'ReactNode'. const jsxWithReactFragment = {test}; ->jsxWithReactFragment : Symbol(jsxWithReactFragment, Decl(index.tsx, 9, 5)) +>jsxWithReactFragment : Symbol(jsxWithReactFragment, Decl(index.tsx, 7, 5)) >React.Fragment : Symbol(React.Fragment, Decl(react18.d.ts, 390, 9)) >React : Symbol(React, Decl(react18.d.ts, 62, 15)) >Fragment : Symbol(React.Fragment, Decl(react18.d.ts, 390, 9)) @@ -23,3 +22,7 @@ const jsxWithReactFragment = {test}; >React : Symbol(React, Decl(react18.d.ts, 62, 15)) >Fragment : Symbol(React.Fragment, Decl(react18.d.ts, 390, 9)) +const jsxNestedFragment = <><>{test}; +>jsxNestedFragment : Symbol(jsxNestedFragment, Decl(index.tsx, 9, 5)) +>test : Symbol(test, Decl(index.tsx, 3, 5)) + diff --git a/tests/baselines/reference/jsxChildWrongFragment.types b/tests/baselines/reference/jsxChildWrongFragment.types index 2ec3d80766092..28440ed042a49 100644 --- a/tests/baselines/reference/jsxChildWrongFragment.types +++ b/tests/baselines/reference/jsxChildWrongFragment.types @@ -15,7 +15,7 @@ const test = () => "asd"; >"asd" : "asd" > : ^^^^^ -// No Errors +// these two should error in the same way const jsxWithJsxFragment = <>{test}; >jsxWithJsxFragment : JSX.Element > : ^^^^^^^^^^^ @@ -24,7 +24,6 @@ const jsxWithJsxFragment = <>{test}; >test : () => string > : ^^^^^^^^^^^^ -// Type '() => string' is not assignable to type 'ReactNode'. const jsxWithReactFragment = {test}; >jsxWithReactFragment : JSX.Element > : ^^^^^^^^^^^ @@ -45,3 +44,13 @@ const jsxWithReactFragment = {test}; >Fragment : React.ExoticComponent<{ children?: React.ReactNode | undefined; }> > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ +const jsxNestedFragment = <><>{test}; +>jsxNestedFragment : JSX.Element +> : ^^^^^^^^^^^ +><><>{test} : JSX.Element +> : ^^^^^^^^^^^ +><>{test} : JSX.Element +> : ^^^^^^^^^^^ +>test : () => string +> : ^^^^^^^^^^^^ + diff --git a/tests/cases/compiler/jsxChildWrongFragment.tsx b/tests/cases/compiler/jsxChildWrongFragment.tsx index 67c4d78dc971b..256e996923ef4 100644 --- a/tests/cases/compiler/jsxChildWrongFragment.tsx +++ b/tests/cases/compiler/jsxChildWrongFragment.tsx @@ -11,8 +11,8 @@ const test = () => "asd"; -// No Errors +// these two should error in the same way const jsxWithJsxFragment = <>{test}; - -// Type '() => string' is not assignable to type 'ReactNode'. const jsxWithReactFragment = {test}; + +const jsxNestedFragment = <><>{test}; From fda397ff14df9c5d24373667f5e2a483bff0c5eb Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Tue, 24 Sep 2024 09:43:10 -0700 Subject: [PATCH 05/16] cache jsxfragment type in nodelinks so we will only error on the first fragment if factory not found --- src/compiler/checker.ts | 53 ++++++++++--------- src/compiler/types.ts | 2 +- ...actoryAndJsxFragmentFactoryNull.errors.txt | 10 +--- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3d75f5ff0f3d8..f241e7249f466 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33168,7 +33168,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else { Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute); if (attributesTable.size > 0) { - spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false); + spread = getSpreadType(spread, createJsxAttributesTypeHelper(), attributes.symbol, objectFlags, /*readonly*/ false); attributesTable = createSymbolTable(); } const exprType = getReducedType(checkExpression(attributeDecl.expression, checkMode & CheckMode.Inferential)); @@ -33190,7 +33190,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (!hasSpreadAnyType) { if (attributesTable.size > 0) { - spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false); + spread = getSpreadType(spread, createJsxAttributesTypeHelper(), attributes.symbol, objectFlags, /*readonly*/ false); } } } @@ -33235,20 +33235,28 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (typeToIntersect && spread !== emptyJsxObjectType) { return getIntersectionType([typeToIntersect, spread]); } - return typeToIntersect || (spread === emptyJsxObjectType ? createJsxAttributesType() : spread); + return typeToIntersect || (spread === emptyJsxObjectType ? createJsxAttributesTypeHelper() : spread); - /** - * Create anonymous type from given attributes symbol table. - * @param symbol a symbol of JsxAttributes containing attributes corresponding to attributesTable - * @param attributesTable a symbol table of attributes property - */ - function createJsxAttributesType() { + function createJsxAttributesTypeHelper() { objectFlags |= ObjectFlags.FreshLiteral; - const result = createAnonymousType(attributesSymbol, attributesTable, emptyArray, emptyArray, emptyArray); - result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; - return result; + return createJsxAttributesType(objectFlags, attributesSymbol, attributesTable); } } + /** + * Create anonymous type from given attributes symbol table. + * @param symbol a symbol of JsxAttributes containing attributes corresponding to attributesTable + * @param attributesTable a symbol table of attributes property + */ + function createJsxAttributesType(objectFlags: ObjectFlags, attributesSymbol: Symbol | undefined, attributesTable: SymbolTable): Type { + const result = createAnonymousType(attributesSymbol, attributesTable, emptyArray, emptyArray, emptyArray); + result.objectFlags |= objectFlags | ObjectFlags.FreshLiteral | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; + return result; + } + + function createEmptyJsxFragmentsAttributesType(): Type { + // Used to synthesize type for `getEffectiveCallArgument`. This attributes Type does not include a children property yet. + return createJsxAttributesType(ObjectFlags.JsxAttributes, /*attributesSymbol*/ undefined, createSymbolTable()); + } function checkJsxChildren(node: JsxElement | JsxFragment, checkMode?: CheckMode) { const childrenTypes: Type[] = []; @@ -35562,7 +35570,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * Returns the effective arguments for an expression that works like a function invocation. */ function getEffectiveCallArguments(node: CallLikeExpression): readonly Expression[] { - if (isJsxOpeningFragment(node)) return emptyArray; + if (isJsxOpeningFragment(node)) return [createSyntheticExpression(node, createEmptyJsxFragmentsAttributesType())]; if (node.kind === SyntaxKind.TaggedTemplateExpression) { const template = node.template; @@ -36798,27 +36806,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getJSXFragmentType(node: JsxOpeningFragment): Type { // An opening fragment is required in order for `getJsxNamespace` to give the fragment factory + const sourceFileLinks = getNodeLinks(getSourceFileOfNode(node)); + if (sourceFileLinks.jsxFragmentType !== undefined) return sourceFileLinks.jsxFragmentType; + const jsxFragmentFactoryName = getJsxNamespace(node); const jsxFactoryRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined; const jsxFactorySymbol = getJsxNamespaceContainerForImplicitImport(node) ?? resolveName(node, jsxFragmentFactoryName, SymbolFlags.Value, /*nameNotFoundMessage*/ jsxFactoryRefErr, /*isUse*/ true); - if (jsxFactorySymbol === undefined) { - return errorType; - } - if (jsxFactorySymbol.escapedName === ReactNames.Fragment) { - return getTypeOfSymbol(jsxFactorySymbol); - } - const resolvedAlias = (jsxFactorySymbol.flags & SymbolFlags.Alias) === 0 ? jsxFactorySymbol : resolveAlias(jsxFactorySymbol); + if (jsxFactorySymbol === undefined) return sourceFileLinks.jsxFragmentType = errorType; + if (jsxFactorySymbol.escapedName === ReactNames.Fragment) return sourceFileLinks.jsxFragmentType = getTypeOfSymbol(jsxFactorySymbol); + const resolvedAlias = (jsxFactorySymbol.flags & SymbolFlags.Alias) === 0 ? jsxFactorySymbol : resolveAlias(jsxFactorySymbol); const reactExports = jsxFactorySymbol && getExportsOfSymbol(resolvedAlias); const typeSymbol = reactExports && getSymbol(reactExports, ReactNames.Fragment, SymbolFlags.BlockScopedVariable); - const type = typeSymbol && getTypeOfSymbol(typeSymbol); - if (type === undefined) { - return errorType; - } - return type; + return sourceFileLinks.jsxFragmentType = type === undefined ? errorType : type; } function resolveJsxOpeningLikeElement(node: JsxCallLike, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6071d07ecfc68..55f3e03733f99 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6219,11 +6219,11 @@ export interface NodeLinks { hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context jsxFlags: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with resolvedJsxElementAttributesType?: Type; // resolved element attributes type of a JSX openinglike element - resolvedJsxElementAllAttributesType?: Type; // resolved all element attributes type of a JSX openinglike element resolvedJSDocType?: Type; // Resolved type of a JSDoc type reference switchTypes?: Type[]; // Cached array of switch case expression types jsxNamespace?: Symbol | false; // Resolved jsx namespace symbol for this node jsxImplicitImportContainer?: Symbol | false; // Resolved module symbol the implicit jsx import of this file should refer to + jsxFragmentType?: Type; // Type of the JSX fragment element, set per SourceFile if a jsxFragment is checked in the file contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive deferredNodes?: Set; // Set of nodes whose checking has been deferred capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement diff --git a/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt index 227df27f1649e..61fd0c28ab245 100644 --- a/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt +++ b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt @@ -1,16 +1,10 @@ jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS2304: Cannot find name 'null'. -jsxFactoryAndJsxFragmentFactoryNull.tsx(4,1): error TS2304: Cannot find name 'null'. -jsxFactoryAndJsxFragmentFactoryNull.tsx(4,17): error TS2304: Cannot find name 'null'. -==== jsxFactoryAndJsxFragmentFactoryNull.tsx (3 errors) ==== +==== jsxFactoryAndJsxFragmentFactoryNull.tsx (1 errors) ==== declare var h: any; <>; ~~ !!! error TS2304: Cannot find name 'null'. - <>1<>2.12.2; - ~~ -!!! error TS2304: Cannot find name 'null'. - ~~ -!!! error TS2304: Cannot find name 'null'. \ No newline at end of file + <>1<>2.12.2; \ No newline at end of file From e9578d466da0594caa215292d0a4b2f8d5ad956e Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Tue, 24 Sep 2024 09:58:19 -0700 Subject: [PATCH 06/16] fix isCallLikeExpression --- src/compiler/utilitiesPublic.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 76ecf3fa12076..36b6968743fa6 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1954,13 +1954,16 @@ export function isCallLikeOrFunctionLikeExpression(node: Node): node is CallLike export function isCallLikeExpression(node: Node): node is CallLikeExpression { switch (node.kind) { - case SyntaxKind.JsxOpeningElement: - case SyntaxKind.JsxSelfClosingElement: case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: case SyntaxKind.TaggedTemplateExpression: case SyntaxKind.Decorator: + case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxSelfClosingElement: + case SyntaxKind.JsxOpeningFragment: return true; + case SyntaxKind.BinaryExpression: + return (node as BinaryExpression).operatorToken.kind === SyntaxKind.InstanceOfKeyword; default: return false; } From 9a83697b1e204a88feeb07e921d148b082979788 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Tue, 24 Sep 2024 12:18:49 -0700 Subject: [PATCH 07/16] update baselines after merge --- .../reference/inlineJsxAndJsxFragPragma.errors.txt | 10 +++++----- .../inlineJsxFactoryWithFragmentIsError.errors.txt | 5 ++++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt b/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt index 8e485202d1c3c..eca3109e19c14 100644 --- a/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt +++ b/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt @@ -1,11 +1,9 @@ preacty-no-fragment.tsx(5,12): error TS6133: 'Fragment' is declared but its value is never read. -preacty-only-fragment-no-jsx.tsx(6,1): error TS2304: Cannot find name 'h'. -snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2304: Cannot find name 'jsx'. +preacty-only-fragment-no-jsx.tsx(6,1): error TS2874: This JSX tag requires 'h' to be in scope, but it could not be found. snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2304: Cannot find name 'null'. +snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2874: This JSX tag requires 'jsx' to be in scope, but it could not be found. snabbdomy-only-fragment.tsx(4,1): error TS2304: Cannot find name 'null'. snabbdomy.tsx(4,1): error TS2304: Cannot find name 'null'. -preacty-only-fragment-no-jsx.tsx(6,1): error TS2874: This JSX tag requires 'h' to be in scope, but it could not be found. -snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2874: This JSX tag requires 'jsx' to be in scope, but it could not be found. ==== renderer.d.ts (0 errors) ==== @@ -68,7 +66,9 @@ snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2874: This JSX tag requires 'js import {} from "./renderer"; <> ~~ -!!! error TS2304: Cannot find name 'jsx'. +!!! error TS2304: Cannot find name 'null'. + ~~ +!!! error TS2874: This JSX tag requires 'jsx' to be in scope, but it could not be found. ==== preacty-no-fragment.tsx (1 errors) ==== /** diff --git a/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt b/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt index 97f6e43717a0e..7bf93025f0c04 100644 --- a/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt +++ b/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt @@ -1,3 +1,4 @@ +index.tsx(3,1): error TS2304: Cannot find name 'React'. index.tsx(3,1): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found. index.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. reacty.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. @@ -19,11 +20,13 @@ reacty.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @js <> ~~~~~~~~~~~~ !!! error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. -==== index.tsx (2 errors) ==== +==== index.tsx (3 errors) ==== /** @jsx dom */ import { dom } from "./renderer"; <> ~~ +!!! error TS2304: Cannot find name 'React'. + ~~ !!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found. ~~~~~~~~~~~~ !!! error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. \ No newline at end of file From 36bb8e7fc326735491d4e12d43dd1e5d32989675 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Tue, 24 Sep 2024 12:29:33 -0700 Subject: [PATCH 08/16] rename test --- .../jsxChildWrongFragment.errors.txt | 32 ------------------- .../reference/jsxFragmentWrongType.errors.txt | 22 +++++++++++++ ...ongFragment.js => jsxFragmentWrongType.js} | 12 ++----- ...t.symbols => jsxFragmentWrongType.symbols} | 19 ++++------- ...gment.types => jsxFragmentWrongType.types} | 15 ++------- tests/cases/compiler/jsxFragmentWrongType.tsx | 15 +++++++++ 6 files changed, 49 insertions(+), 66 deletions(-) delete mode 100644 tests/baselines/reference/jsxChildWrongFragment.errors.txt create mode 100644 tests/baselines/reference/jsxFragmentWrongType.errors.txt rename tests/baselines/reference/{jsxChildWrongFragment.js => jsxFragmentWrongType.js} (59%) rename tests/baselines/reference/{jsxChildWrongFragment.symbols => jsxFragmentWrongType.symbols} (51%) rename tests/baselines/reference/{jsxChildWrongFragment.types => jsxFragmentWrongType.types} (77%) create mode 100644 tests/cases/compiler/jsxFragmentWrongType.tsx diff --git a/tests/baselines/reference/jsxChildWrongFragment.errors.txt b/tests/baselines/reference/jsxChildWrongFragment.errors.txt deleted file mode 100644 index 5af6adf1cc929..0000000000000 --- a/tests/baselines/reference/jsxChildWrongFragment.errors.txt +++ /dev/null @@ -1,32 +0,0 @@ -index.tsx(7,28): error TS2322: Type '{ children: () => string; }' is not assignable to type '{ children?: ReactNode; }'. - Types of property 'children' are incompatible. - Type '() => string' is not assignable to type 'ReactNode'. -index.tsx(8,47): error TS2322: Type '() => string' is not assignable to type 'ReactNode'. -index.tsx(10,29): error TS2322: Type '{ children: () => string; }' is not assignable to type '{ children?: ReactNode; }'. - Types of property 'children' are incompatible. - Type '() => string' is not assignable to type 'ReactNode'. - - -==== index.tsx (3 errors) ==== - /// - /// - - const test = () => "asd"; - - // these two should error in the same way - const jsxWithJsxFragment = <>{test}; - ~~ -!!! error TS2322: Type '{ children: () => string; }' is not assignable to type '{ children?: ReactNode; }'. -!!! error TS2322: Types of property 'children' are incompatible. -!!! error TS2322: Type '() => string' is not assignable to type 'ReactNode'. - const jsxWithReactFragment = {test}; - ~~~~ -!!! error TS2322: Type '() => string' is not assignable to type 'ReactNode'. -!!! related TS6212 index.tsx:8:47: Did you mean to call this expression? - - const jsxNestedFragment = <><>{test}; - ~~ -!!! error TS2322: Type '{ children: () => string; }' is not assignable to type '{ children?: ReactNode; }'. -!!! error TS2322: Types of property 'children' are incompatible. -!!! error TS2322: Type '() => string' is not assignable to type 'ReactNode'. - \ No newline at end of file diff --git a/tests/baselines/reference/jsxFragmentWrongType.errors.txt b/tests/baselines/reference/jsxFragmentWrongType.errors.txt new file mode 100644 index 0000000000000..f979faf99b4f8 --- /dev/null +++ b/tests/baselines/reference/jsxFragmentWrongType.errors.txt @@ -0,0 +1,22 @@ +a.tsx(6,28): error TS2322: Type '{ children: () => string; }' is not assignable to type '{ children?: ReactNode; }'. + Types of property 'children' are incompatible. + Type '() => string' is not assignable to type 'ReactNode'. +a.tsx(7,47): error TS2322: Type '() => string' is not assignable to type 'ReactNode'. + + +==== a.tsx (2 errors) ==== + /// + /// + + const test = () => "asd"; + + const jsxWithJsxFragment = <>{test}; + ~~ +!!! error TS2322: Type '{ children: () => string; }' is not assignable to type '{ children?: ReactNode; }'. +!!! error TS2322: Types of property 'children' are incompatible. +!!! error TS2322: Type '() => string' is not assignable to type 'ReactNode'. + const jsxWithReactFragment = {test}; + ~~~~ +!!! error TS2322: Type '() => string' is not assignable to type 'ReactNode'. +!!! related TS6212 a.tsx:7:47: Did you mean to call this expression? + \ No newline at end of file diff --git a/tests/baselines/reference/jsxChildWrongFragment.js b/tests/baselines/reference/jsxFragmentWrongType.js similarity index 59% rename from tests/baselines/reference/jsxChildWrongFragment.js rename to tests/baselines/reference/jsxFragmentWrongType.js index 79b221236c4f7..1ae32537896e1 100644 --- a/tests/baselines/reference/jsxChildWrongFragment.js +++ b/tests/baselines/reference/jsxFragmentWrongType.js @@ -1,25 +1,19 @@ -//// [tests/cases/compiler/jsxChildWrongFragment.tsx] //// +//// [tests/cases/compiler/jsxFragmentWrongType.tsx] //// -//// [index.tsx] +//// [a.tsx] /// /// const test = () => "asd"; -// these two should error in the same way const jsxWithJsxFragment = <>{test}; const jsxWithReactFragment = {test}; - -const jsxNestedFragment = <><>{test}; -//// [index.js] +//// [a.js] "use strict"; /// /// const test = () => "asd"; -// these two should error in the same way const jsxWithJsxFragment = React.createElement(React.Fragment, null, test); const jsxWithReactFragment = React.createElement(React.Fragment, null, test); -const jsxNestedFragment = React.createElement(React.Fragment, null, - React.createElement(React.Fragment, null, test)); diff --git a/tests/baselines/reference/jsxChildWrongFragment.symbols b/tests/baselines/reference/jsxFragmentWrongType.symbols similarity index 51% rename from tests/baselines/reference/jsxChildWrongFragment.symbols rename to tests/baselines/reference/jsxFragmentWrongType.symbols index 9322c9aa77f74..75ddb916c3af6 100644 --- a/tests/baselines/reference/jsxChildWrongFragment.symbols +++ b/tests/baselines/reference/jsxFragmentWrongType.symbols @@ -1,28 +1,23 @@ -//// [tests/cases/compiler/jsxChildWrongFragment.tsx] //// +//// [tests/cases/compiler/jsxFragmentWrongType.tsx] //// -=== index.tsx === +=== a.tsx === /// /// const test = () => "asd"; ->test : Symbol(test, Decl(index.tsx, 3, 5)) +>test : Symbol(test, Decl(a.tsx, 3, 5)) -// these two should error in the same way const jsxWithJsxFragment = <>{test}; ->jsxWithJsxFragment : Symbol(jsxWithJsxFragment, Decl(index.tsx, 6, 5)) ->test : Symbol(test, Decl(index.tsx, 3, 5)) +>jsxWithJsxFragment : Symbol(jsxWithJsxFragment, Decl(a.tsx, 5, 5)) +>test : Symbol(test, Decl(a.tsx, 3, 5)) const jsxWithReactFragment = {test}; ->jsxWithReactFragment : Symbol(jsxWithReactFragment, Decl(index.tsx, 7, 5)) +>jsxWithReactFragment : Symbol(jsxWithReactFragment, Decl(a.tsx, 6, 5)) >React.Fragment : Symbol(React.Fragment, Decl(react18.d.ts, 390, 9)) >React : Symbol(React, Decl(react18.d.ts, 62, 15)) >Fragment : Symbol(React.Fragment, Decl(react18.d.ts, 390, 9)) ->test : Symbol(test, Decl(index.tsx, 3, 5)) +>test : Symbol(test, Decl(a.tsx, 3, 5)) >React.Fragment : Symbol(React.Fragment, Decl(react18.d.ts, 390, 9)) >React : Symbol(React, Decl(react18.d.ts, 62, 15)) >Fragment : Symbol(React.Fragment, Decl(react18.d.ts, 390, 9)) -const jsxNestedFragment = <><>{test}; ->jsxNestedFragment : Symbol(jsxNestedFragment, Decl(index.tsx, 9, 5)) ->test : Symbol(test, Decl(index.tsx, 3, 5)) - diff --git a/tests/baselines/reference/jsxChildWrongFragment.types b/tests/baselines/reference/jsxFragmentWrongType.types similarity index 77% rename from tests/baselines/reference/jsxChildWrongFragment.types rename to tests/baselines/reference/jsxFragmentWrongType.types index 28440ed042a49..ad96ba1bd905c 100644 --- a/tests/baselines/reference/jsxChildWrongFragment.types +++ b/tests/baselines/reference/jsxFragmentWrongType.types @@ -1,9 +1,9 @@ -//// [tests/cases/compiler/jsxChildWrongFragment.tsx] //// +//// [tests/cases/compiler/jsxFragmentWrongType.tsx] //// === Performance Stats === Type Count: 1,000 -=== index.tsx === +=== a.tsx === /// /// @@ -15,7 +15,6 @@ const test = () => "asd"; >"asd" : "asd" > : ^^^^^ -// these two should error in the same way const jsxWithJsxFragment = <>{test}; >jsxWithJsxFragment : JSX.Element > : ^^^^^^^^^^^ @@ -44,13 +43,3 @@ const jsxWithReactFragment = {test}; >Fragment : React.ExoticComponent<{ children?: React.ReactNode | undefined; }> > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ -const jsxNestedFragment = <><>{test}; ->jsxNestedFragment : JSX.Element -> : ^^^^^^^^^^^ -><><>{test} : JSX.Element -> : ^^^^^^^^^^^ -><>{test} : JSX.Element -> : ^^^^^^^^^^^ ->test : () => string -> : ^^^^^^^^^^^^ - diff --git a/tests/cases/compiler/jsxFragmentWrongType.tsx b/tests/cases/compiler/jsxFragmentWrongType.tsx new file mode 100644 index 0000000000000..2543974288ce9 --- /dev/null +++ b/tests/cases/compiler/jsxFragmentWrongType.tsx @@ -0,0 +1,15 @@ +// @jsx: react +// @strict: true +// @skipLibCheck: true +// @target: ES2017 +// @module: ESNext +// @esModuleInterop: true + +// @filename: a.tsx +/// +/// + +const test = () => "asd"; + +const jsxWithJsxFragment = <>{test}; +const jsxWithReactFragment = {test}; From fb8defa5fcfad185e7e0a357976e2cd64829adb5 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Tue, 24 Sep 2024 12:32:34 -0700 Subject: [PATCH 09/16] rename test --- tests/cases/compiler/jsxChildWrongFragment.tsx | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 tests/cases/compiler/jsxChildWrongFragment.tsx diff --git a/tests/cases/compiler/jsxChildWrongFragment.tsx b/tests/cases/compiler/jsxChildWrongFragment.tsx deleted file mode 100644 index 256e996923ef4..0000000000000 --- a/tests/cases/compiler/jsxChildWrongFragment.tsx +++ /dev/null @@ -1,18 +0,0 @@ -// @jsx: react -// @strict: true -// @target: ES2017 -// @module: ESNext -// @esModuleInterop: true -// @skipLibCheck: true - -// @filename: index.tsx -/// -/// - -const test = () => "asd"; - -// these two should error in the same way -const jsxWithJsxFragment = <>{test}; -const jsxWithReactFragment = {test}; - -const jsxNestedFragment = <><>{test}; From 37652305cf9995a6159623604ea5821568a463cf Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Wed, 25 Sep 2024 15:26:03 -0700 Subject: [PATCH 10/16] create type for empty fragment attributes only once --- src/compiler/checker.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e0908cf3bfd95..a606be97e1f61 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2116,6 +2116,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var emptyObjectType = createAnonymousType(/*symbol*/ undefined, emptySymbols, emptyArray, emptyArray, emptyArray); var emptyJsxObjectType = createAnonymousType(/*symbol*/ undefined, emptySymbols, emptyArray, emptyArray, emptyArray); emptyJsxObjectType.objectFlags |= ObjectFlags.JsxAttributes; + var emptyFreshJsxObjectType = createAnonymousType(/*symbol*/ undefined, emptySymbols, emptyArray, emptyArray, emptyArray); + emptyFreshJsxObjectType.objectFlags |= ObjectFlags.JsxAttributes | ObjectFlags.FreshLiteral | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; var emptyTypeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type); emptyTypeLiteralSymbol.members = createSymbolTable(); @@ -33346,11 +33348,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return result; } - function createEmptyJsxFragmentsAttributesType(): Type { - // Used to synthesize type for `getEffectiveCallArgument`. This attributes Type does not include a children property yet. - return createJsxAttributesType(ObjectFlags.JsxAttributes, /*attributesSymbol*/ undefined, createSymbolTable()); - } - function checkJsxChildren(node: JsxElement | JsxFragment, checkMode?: CheckMode) { const childrenTypes: Type[] = []; for (const child of node.children) { @@ -35663,7 +35660,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * Returns the effective arguments for an expression that works like a function invocation. */ function getEffectiveCallArguments(node: CallLikeExpression): readonly Expression[] { - if (isJsxOpeningFragment(node)) return [createSyntheticExpression(node, createEmptyJsxFragmentsAttributesType())]; + if (isJsxOpeningFragment(node)) { + // This attributes Type does not include a children property yet, the same way a fragment created with does not at this stage + return [createSyntheticExpression(node, emptyFreshJsxObjectType)]; + } if (node.kind === SyntaxKind.TaggedTemplateExpression) { const template = node.template; From bea0cba809f71d99c4c0e1b1b18807d7f95a9fb3 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Wed, 25 Sep 2024 23:26:19 -0700 Subject: [PATCH 11/16] revert error message change --- src/compiler/checker.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a606be97e1f61..72be61c5fe1fd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -35464,6 +35464,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (getJsxNamespaceContainerForImplicitImport(node)) { return true; // factory is implicitly jsx/jsxdev - assume it fits the bill, since we don't strongly look for the jsx/jsxs/jsxDEV factory APIs anywhere else (at least not yet) } + + // We assume fragments have the correct arity since the node does not have attributes const tagType = (isJsxOpeningElement(node) || isJsxSelfClosingElement(node)) && !(isJsxIntrinsicTagName(node.tagName) || isJsxNamespacedName(node.tagName)) ? checkExpression(node.tagName) : undefined; if (!tagType) { return true; @@ -35522,12 +35524,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (reportErrors) { - const errorNode = isJsxOpeningFragment(node) ? node : node.tagName; - const errorEntityName = isJsxOpeningFragment(node) ? "Fragment" : entityNameToString(node.tagName); - const diag = createDiagnosticForNode(errorNode, Diagnostics.Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3, errorEntityName, absoluteMinArgCount, entityNameToString(factory), maxParamCount); - const tagNameDeclaration = isJsxOpeningFragment(node) ? getJSXFragmentType(node).symbol.valueDeclaration : getSymbolAtLocation(node.tagName)?.valueDeclaration; + // We will not report errors in this function for fragments, since we do not check them in this function + const tagName = (node as JsxOpeningElement | JsxSelfClosingElement).tagName; + const diag = createDiagnosticForNode(tagName, Diagnostics.Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3, entityNameToString(tagName), absoluteMinArgCount, entityNameToString(factory), maxParamCount); + const tagNameDeclaration = getSymbolAtLocation(tagName)?.valueDeclaration; if (tagNameDeclaration) { - addRelatedInfo(diag, createDiagnosticForNode(tagNameDeclaration, Diagnostics._0_is_declared_here, errorEntityName)); + addRelatedInfo(diag, createDiagnosticForNode(tagNameDeclaration, Diagnostics._0_is_declared_here, entityNameToString(tagName))); } if (errorOutputContainer && errorOutputContainer.skipLogging) { (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag); From 6a20cc650212157f01600b88c4530a1182b12536 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Thu, 26 Sep 2024 15:24:36 -0700 Subject: [PATCH 12/16] update error messages --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticMessages.json | 5 ++++- .../reference/inlineJsxAndJsxFragPragma.errors.txt | 14 +++++++------- ...sxFragPragmaOverridesCompilerOptions.errors.txt | 4 ++-- .../inlineJsxFactoryWithFragmentIsError.errors.txt | 6 +++--- .../jsxFactoryAndJsxFragmentFactoryNull.errors.txt | 4 ++-- ...TransformCustomImport(jsx=react-jsx).errors.txt | 5 ++++- ...nsformCustomImport(jsx=react-jsxdev).errors.txt | 5 ++++- ...ormCustomImportPragma(jsx=react-jsx).errors.txt | 5 ++++- ...CustomImportPragma(jsx=react-jsxdev).errors.txt | 5 ++++- ...UnaryExpressionNoTypeAssertionInJsx2.errors.txt | 5 ++++- ...UnaryExpressionNoTypeAssertionInJsx4.errors.txt | 5 ++++- 12 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 72be61c5fe1fd..ef743bb7c82e3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -36905,7 +36905,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (sourceFileLinks.jsxFragmentType !== undefined) return sourceFileLinks.jsxFragmentType; const jsxFragmentFactoryName = getJsxNamespace(node); - const jsxFactoryRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined; + const jsxFactoryRefErr = diagnostics ? Diagnostics.Cannot_find_name_0_the_fragment_factory_which_is_required_to_use_fragments : undefined; const jsxFactorySymbol = getJsxNamespaceContainerForImplicitImport(node) ?? resolveName(node, jsxFragmentFactoryName, SymbolFlags.Value, /*nameNotFoundMessage*/ jsxFactoryRefErr, /*isUse*/ true); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 944b08c4d15b0..6c7ac968dd953 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -5510,7 +5510,6 @@ "category": "Message", "code": 6243 }, - "Modules": { "category": "Message", "code": 6244 @@ -5603,6 +5602,10 @@ "category": "Error", "code": 6266 }, + "Cannot find name '{0}', the fragment factory, which is required to use fragments.": { + "category": "Error", + "code": 6267 + }, "Directory '{0}' has no containing package.json scope. Imports will not resolve.": { "category": "Message", diff --git a/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt b/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt index eca3109e19c14..fc2fc5f98d664 100644 --- a/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt +++ b/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt @@ -1,9 +1,9 @@ preacty-no-fragment.tsx(5,12): error TS6133: 'Fragment' is declared but its value is never read. preacty-only-fragment-no-jsx.tsx(6,1): error TS2874: This JSX tag requires 'h' to be in scope, but it could not be found. -snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2304: Cannot find name 'null'. snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2874: This JSX tag requires 'jsx' to be in scope, but it could not be found. -snabbdomy-only-fragment.tsx(4,1): error TS2304: Cannot find name 'null'. -snabbdomy.tsx(4,1): error TS2304: Cannot find name 'null'. +snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. +snabbdomy-only-fragment.tsx(4,1): error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. +snabbdomy.tsx(4,1): error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. ==== renderer.d.ts (0 errors) ==== @@ -32,7 +32,7 @@ snabbdomy.tsx(4,1): error TS2304: Cannot find name 'null'. import {jsx} from "./renderer"; <> ~~ -!!! error TS2304: Cannot find name 'null'. +!!! error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. ==== preacty-only-fragment.tsx (0 errors) ==== /** @@ -48,7 +48,7 @@ snabbdomy.tsx(4,1): error TS2304: Cannot find name 'null'. import {jsx} from "./renderer"; <> ~~ -!!! error TS2304: Cannot find name 'null'. +!!! error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. ==== preacty-only-fragment-no-jsx.tsx (1 errors) ==== /** @@ -66,9 +66,9 @@ snabbdomy.tsx(4,1): error TS2304: Cannot find name 'null'. import {} from "./renderer"; <> ~~ -!!! error TS2304: Cannot find name 'null'. - ~~ !!! error TS2874: This JSX tag requires 'jsx' to be in scope, but it could not be found. + ~~ +!!! error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. ==== preacty-no-fragment.tsx (1 errors) ==== /** diff --git a/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt b/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt index a9e365970bc41..b074f23bf9c6b 100644 --- a/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt +++ b/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt @@ -1,4 +1,4 @@ -snabbdomy.tsx(6,1): error TS2304: Cannot find name 'null'. +snabbdomy.tsx(6,1): error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. ==== react.d.ts (0 errors) ==== @@ -39,7 +39,7 @@ snabbdomy.tsx(6,1): error TS2304: Cannot find name 'null'. import {h} from "./snabbdom"; <>
~~ -!!! error TS2304: Cannot find name 'null'. +!!! error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. ==== mix-n-match.tsx (0 errors) ==== /* @jsx h */ diff --git a/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt b/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt index 7bf93025f0c04..1b1dc1006d839 100644 --- a/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt +++ b/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt @@ -1,5 +1,5 @@ -index.tsx(3,1): error TS2304: Cannot find name 'React'. index.tsx(3,1): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found. +index.tsx(3,1): error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. index.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. reacty.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. @@ -25,8 +25,8 @@ reacty.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @js import { dom } from "./renderer"; <> ~~ -!!! error TS2304: Cannot find name 'React'. - ~~ !!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found. + ~~ +!!! error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. ~~~~~~~~~~~~ !!! error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. \ No newline at end of file diff --git a/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt index 61fd0c28ab245..0c4e09f460caa 100644 --- a/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt +++ b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt @@ -1,4 +1,4 @@ -jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS2304: Cannot find name 'null'. +jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. ==== jsxFactoryAndJsxFragmentFactoryNull.tsx (1 errors) ==== @@ -6,5 +6,5 @@ jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS2304: Cannot find name 'nu <>; ~~ -!!! error TS2304: Cannot find name 'null'. +!!! error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. <>1<>2.12.2; \ No newline at end of file diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt index 248540ed384da..da259b8453e0e 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt @@ -1,11 +1,14 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. +jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. -==== jsxJsxsCjsTransformCustomImport.tsx (1 errors) ==== +==== jsxJsxsCjsTransformCustomImport.tsx (2 errors) ==== /// const a = <> ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. + ~~ +!!! error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments.

text
diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt index e66480f8dce2f..9333b43932577 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt @@ -1,11 +1,14 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. +jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. -==== jsxJsxsCjsTransformCustomImport.tsx (1 errors) ==== +==== jsxJsxsCjsTransformCustomImport.tsx (2 errors) ==== /// const a = <> ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. + ~~ +!!! error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments.

text
diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt index c37e010cab834..f38b1708b78d7 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt @@ -1,4 +1,5 @@ preact.tsx(3,11): error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. +preact.tsx(3,11): error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. ==== react.tsx (0 errors) ==== @@ -12,12 +13,14 @@ preact.tsx(3,11): error TS2875: This JSX tag requires the module path 'preact/js export {}; -==== preact.tsx (1 errors) ==== +==== preact.tsx (2 errors) ==== /// /* @jsxImportSource preact */ const a = <> ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. + ~~ +!!! error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments.

text
diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt index 79e8e02a87b2f..c14de14542c80 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt @@ -1,4 +1,5 @@ preact.tsx(3,11): error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. +preact.tsx(3,11): error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. ==== react.tsx (0 errors) ==== @@ -12,12 +13,14 @@ preact.tsx(3,11): error TS2875: This JSX tag requires the module path 'preact/js export {}; -==== preact.tsx (1 errors) ==== +==== preact.tsx (2 errors) ==== /// /* @jsxImportSource preact */ const a = <> ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. + ~~ +!!! error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments.

text
diff --git a/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt b/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt index 69e07e52360a5..5bc93ce90cd3a 100644 --- a/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt +++ b/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt @@ -1,14 +1,17 @@ index.js(2,12): error TS17014: JSX fragment has no corresponding closing tag. +index.js(2,13): error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. index.js(2,13): error TS17004: Cannot use JSX unless the '--jsx' flag is provided. index.js(3,1): error TS1005: ' x; ~~~ !!! error TS17014: JSX fragment has no corresponding closing tag. ~~ +!!! error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. + ~~ !!! error TS17004: Cannot use JSX unless the '--jsx' flag is provided. diff --git a/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx4.errors.txt b/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx4.errors.txt index 2c200912716c1..8e36d4f981f9b 100644 --- a/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx4.errors.txt +++ b/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx4.errors.txt @@ -1,11 +1,12 @@ index.tsx(3,14): error TS17008: JSX element 'number' has no corresponding closing tag. +index.tsx(4,13): error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. index.tsx(4,13): error TS17014: JSX fragment has no corresponding closing tag. index.tsx(5,14): error TS1003: Identifier expected. index.tsx(5,18): error TS1382: Unexpected token. Did you mean `{'>'}` or `>`? index.tsx(6,1): error TS1005: ' x; @@ -13,6 +14,8 @@ index.tsx(6,1): error TS1005: ' x; ~~ +!!! error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. + ~~ !!! error TS17014: JSX fragment has no corresponding closing tag. const c = + <1234> x; ~~~~ From eb498b4b1ef74062e3be664e9b23ec5b357514a0 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Thu, 26 Sep 2024 15:32:14 -0700 Subject: [PATCH 13/16] Update diagnostic message again --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticMessages.json | 8 ++++---- .../reference/inlineJsxAndJsxFragPragma.errors.txt | 12 ++++++------ ...dJsxFragPragmaOverridesCompilerOptions.errors.txt | 4 ++-- .../inlineJsxFactoryWithFragmentIsError.errors.txt | 4 ++-- .../jsxFactoryAndJsxFragmentFactoryNull.errors.txt | 4 ++-- ...jsTransformCustomImport(jsx=react-jsx).errors.txt | 4 ++-- ...ransformCustomImport(jsx=react-jsxdev).errors.txt | 4 ++-- ...sformCustomImportPragma(jsx=react-jsx).errors.txt | 4 ++-- ...rmCustomImportPragma(jsx=react-jsxdev).errors.txt | 4 ++-- ...seUnaryExpressionNoTypeAssertionInJsx2.errors.txt | 4 ++-- ...seUnaryExpressionNoTypeAssertionInJsx4.errors.txt | 4 ++-- 12 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ef743bb7c82e3..7b7a9c19486bc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -36905,7 +36905,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (sourceFileLinks.jsxFragmentType !== undefined) return sourceFileLinks.jsxFragmentType; const jsxFragmentFactoryName = getJsxNamespace(node); - const jsxFactoryRefErr = diagnostics ? Diagnostics.Cannot_find_name_0_the_fragment_factory_which_is_required_to_use_fragments : undefined; + const jsxFactoryRefErr = diagnostics ? Diagnostics.Using_JSX_fragments_requires_fragment_factory_0_to_be_in_scope_but_it_could_not_be_found : undefined; const jsxFactorySymbol = getJsxNamespaceContainerForImplicitImport(node) ?? resolveName(node, jsxFragmentFactoryName, SymbolFlags.Value, /*nameNotFoundMessage*/ jsxFactoryRefErr, /*isUse*/ true); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6c7ac968dd953..80c2679101705 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3956,6 +3956,10 @@ "category": "Error", "code": 2875 }, + "Using JSX fragments requires fragment factory '{0}' to be in scope, but it could not be found.": { + "category": "Error", + "code": 6876 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", @@ -5602,10 +5606,6 @@ "category": "Error", "code": 6266 }, - "Cannot find name '{0}', the fragment factory, which is required to use fragments.": { - "category": "Error", - "code": 6267 - }, "Directory '{0}' has no containing package.json scope. Imports will not resolve.": { "category": "Message", diff --git a/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt b/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt index fc2fc5f98d664..1fa5f48aea786 100644 --- a/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt +++ b/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt @@ -1,9 +1,9 @@ preacty-no-fragment.tsx(5,12): error TS6133: 'Fragment' is declared but its value is never read. preacty-only-fragment-no-jsx.tsx(6,1): error TS2874: This JSX tag requires 'h' to be in scope, but it could not be found. snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2874: This JSX tag requires 'jsx' to be in scope, but it could not be found. -snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. -snabbdomy-only-fragment.tsx(4,1): error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. -snabbdomy.tsx(4,1): error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. +snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +snabbdomy-only-fragment.tsx(4,1): error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +snabbdomy.tsx(4,1): error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== renderer.d.ts (0 errors) ==== @@ -32,7 +32,7 @@ snabbdomy.tsx(4,1): error TS6267: Cannot find name 'null', the fragment factory, import {jsx} from "./renderer"; <> ~~ -!!! error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. +!!! error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== preacty-only-fragment.tsx (0 errors) ==== /** @@ -48,7 +48,7 @@ snabbdomy.tsx(4,1): error TS6267: Cannot find name 'null', the fragment factory, import {jsx} from "./renderer"; <> ~~ -!!! error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. +!!! error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== preacty-only-fragment-no-jsx.tsx (1 errors) ==== /** @@ -68,7 +68,7 @@ snabbdomy.tsx(4,1): error TS6267: Cannot find name 'null', the fragment factory, ~~ !!! error TS2874: This JSX tag requires 'jsx' to be in scope, but it could not be found. ~~ -!!! error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. +!!! error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== preacty-no-fragment.tsx (1 errors) ==== /** diff --git a/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt b/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt index b074f23bf9c6b..f618477e18613 100644 --- a/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt +++ b/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt @@ -1,4 +1,4 @@ -snabbdomy.tsx(6,1): error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. +snabbdomy.tsx(6,1): error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== react.d.ts (0 errors) ==== @@ -39,7 +39,7 @@ snabbdomy.tsx(6,1): error TS6267: Cannot find name 'null', the fragment factory, import {h} from "./snabbdom"; <>
~~ -!!! error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. +!!! error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== mix-n-match.tsx (0 errors) ==== /* @jsx h */ diff --git a/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt b/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt index 1b1dc1006d839..10400daf264c0 100644 --- a/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt +++ b/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt @@ -1,5 +1,5 @@ index.tsx(3,1): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found. -index.tsx(3,1): error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. +index.tsx(3,1): error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. index.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. reacty.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. @@ -27,6 +27,6 @@ reacty.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @js ~~ !!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found. ~~ -!!! error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. +!!! error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ~~~~~~~~~~~~ !!! error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. \ No newline at end of file diff --git a/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt index 0c4e09f460caa..48a5be5d2c9d0 100644 --- a/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt +++ b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt @@ -1,4 +1,4 @@ -jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. +jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== jsxFactoryAndJsxFragmentFactoryNull.tsx (1 errors) ==== @@ -6,5 +6,5 @@ jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS6267: Cannot find name 'nu <>; ~~ -!!! error TS6267: Cannot find name 'null', the fragment factory, which is required to use fragments. +!!! error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. <>1<>2.12.2; \ No newline at end of file diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt index da259b8453e0e..e30d4f6bb63f0 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt @@ -1,5 +1,5 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. -jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. +jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ==== jsxJsxsCjsTransformCustomImport.tsx (2 errors) ==== @@ -8,7 +8,7 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS6267: Cannot find name 'React ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. ~~ -!!! error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. +!!! error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.

text
diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt index 9333b43932577..a89eba3da983e 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt @@ -1,5 +1,5 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. -jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. +jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ==== jsxJsxsCjsTransformCustomImport.tsx (2 errors) ==== @@ -8,7 +8,7 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS6267: Cannot find name 'React ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. ~~ -!!! error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. +!!! error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.

text
diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt index f38b1708b78d7..8f9e733a2df16 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt @@ -1,5 +1,5 @@ preact.tsx(3,11): error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. -preact.tsx(3,11): error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. +preact.tsx(3,11): error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ==== react.tsx (0 errors) ==== @@ -20,7 +20,7 @@ preact.tsx(3,11): error TS6267: Cannot find name 'React', the fragment factory, ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. ~~ -!!! error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. +!!! error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.

text
diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt index c14de14542c80..7f6fff30ca667 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt @@ -1,5 +1,5 @@ preact.tsx(3,11): error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. -preact.tsx(3,11): error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. +preact.tsx(3,11): error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ==== react.tsx (0 errors) ==== @@ -20,7 +20,7 @@ preact.tsx(3,11): error TS6267: Cannot find name 'React', the fragment factory, ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. ~~ -!!! error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. +!!! error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.

text
diff --git a/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt b/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt index 5bc93ce90cd3a..e486b48902f53 100644 --- a/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt +++ b/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt @@ -1,5 +1,5 @@ index.js(2,12): error TS17014: JSX fragment has no corresponding closing tag. -index.js(2,13): error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. +index.js(2,13): error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. index.js(2,13): error TS17004: Cannot use JSX unless the '--jsx' flag is provided. index.js(3,1): error TS1005: ''}` or `>`? @@ -14,7 +14,7 @@ index.tsx(6,1): error TS1005: ' x; ~~ -!!! error TS6267: Cannot find name 'React', the fragment factory, which is required to use fragments. +!!! error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ~~ !!! error TS17014: JSX fragment has no corresponding closing tag. const c = + <1234> x; From 0250e44d9a04c3f5f1098fe366ea8ce92b25a050 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Thu, 26 Sep 2024 15:43:00 -0700 Subject: [PATCH 14/16] number typo --- src/compiler/diagnosticMessages.json | 2 +- .../reference/inlineJsxAndJsxFragPragma.errors.txt | 12 ++++++------ ...dJsxFragPragmaOverridesCompilerOptions.errors.txt | 4 ++-- .../inlineJsxFactoryWithFragmentIsError.errors.txt | 4 ++-- .../jsxFactoryAndJsxFragmentFactoryNull.errors.txt | 4 ++-- ...jsTransformCustomImport(jsx=react-jsx).errors.txt | 4 ++-- ...ransformCustomImport(jsx=react-jsxdev).errors.txt | 4 ++-- ...sformCustomImportPragma(jsx=react-jsx).errors.txt | 4 ++-- ...rmCustomImportPragma(jsx=react-jsxdev).errors.txt | 4 ++-- ...seUnaryExpressionNoTypeAssertionInJsx2.errors.txt | 4 ++-- ...seUnaryExpressionNoTypeAssertionInJsx4.errors.txt | 4 ++-- 11 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 80c2679101705..c813e88f32800 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3958,7 +3958,7 @@ }, "Using JSX fragments requires fragment factory '{0}' to be in scope, but it could not be found.": { "category": "Error", - "code": 6876 + "code": 2876 }, "Import declaration '{0}' is using private name '{1}'.": { diff --git a/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt b/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt index 1fa5f48aea786..422e343f36a69 100644 --- a/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt +++ b/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt @@ -1,9 +1,9 @@ preacty-no-fragment.tsx(5,12): error TS6133: 'Fragment' is declared but its value is never read. preacty-only-fragment-no-jsx.tsx(6,1): error TS2874: This JSX tag requires 'h' to be in scope, but it could not be found. snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2874: This JSX tag requires 'jsx' to be in scope, but it could not be found. -snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. -snabbdomy-only-fragment.tsx(4,1): error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. -snabbdomy.tsx(4,1): error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +snabbdomy-only-fragment.tsx(4,1): error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +snabbdomy.tsx(4,1): error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== renderer.d.ts (0 errors) ==== @@ -32,7 +32,7 @@ snabbdomy.tsx(4,1): error TS6876: Using JSX fragments requires fragment factory import {jsx} from "./renderer"; <> ~~ -!!! error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +!!! error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== preacty-only-fragment.tsx (0 errors) ==== /** @@ -48,7 +48,7 @@ snabbdomy.tsx(4,1): error TS6876: Using JSX fragments requires fragment factory import {jsx} from "./renderer"; <> ~~ -!!! error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +!!! error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== preacty-only-fragment-no-jsx.tsx (1 errors) ==== /** @@ -68,7 +68,7 @@ snabbdomy.tsx(4,1): error TS6876: Using JSX fragments requires fragment factory ~~ !!! error TS2874: This JSX tag requires 'jsx' to be in scope, but it could not be found. ~~ -!!! error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +!!! error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== preacty-no-fragment.tsx (1 errors) ==== /** diff --git a/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt b/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt index f618477e18613..c21a12381f72d 100644 --- a/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt +++ b/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt @@ -1,4 +1,4 @@ -snabbdomy.tsx(6,1): error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +snabbdomy.tsx(6,1): error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== react.d.ts (0 errors) ==== @@ -39,7 +39,7 @@ snabbdomy.tsx(6,1): error TS6876: Using JSX fragments requires fragment factory import {h} from "./snabbdom"; <>
~~ -!!! error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +!!! error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== mix-n-match.tsx (0 errors) ==== /* @jsx h */ diff --git a/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt b/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt index 10400daf264c0..403b841c71d26 100644 --- a/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt +++ b/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt @@ -1,5 +1,5 @@ index.tsx(3,1): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found. -index.tsx(3,1): error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +index.tsx(3,1): error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. index.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. reacty.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. @@ -27,6 +27,6 @@ reacty.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @js ~~ !!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found. ~~ -!!! error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +!!! error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ~~~~~~~~~~~~ !!! error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. \ No newline at end of file diff --git a/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt index 48a5be5d2c9d0..2804285fca3a2 100644 --- a/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt +++ b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt @@ -1,4 +1,4 @@ -jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== jsxFactoryAndJsxFragmentFactoryNull.tsx (1 errors) ==== @@ -6,5 +6,5 @@ jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS6876: Using JSX fragments <>; ~~ -!!! error TS6876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +!!! error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. <>1<>2.12.2; \ No newline at end of file diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt index e30d4f6bb63f0..caf4fb3f3d654 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt @@ -1,5 +1,5 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. -jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ==== jsxJsxsCjsTransformCustomImport.tsx (2 errors) ==== @@ -8,7 +8,7 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS6876: Using JSX fragments req ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. ~~ -!!! error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +!!! error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.

text
diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt index a89eba3da983e..1422559073554 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt @@ -1,5 +1,5 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. -jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ==== jsxJsxsCjsTransformCustomImport.tsx (2 errors) ==== @@ -8,7 +8,7 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS6876: Using JSX fragments req ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. ~~ -!!! error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +!!! error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.

text
diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt index 8f9e733a2df16..17e403fafb8bf 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt @@ -1,5 +1,5 @@ preact.tsx(3,11): error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. -preact.tsx(3,11): error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +preact.tsx(3,11): error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ==== react.tsx (0 errors) ==== @@ -20,7 +20,7 @@ preact.tsx(3,11): error TS6876: Using JSX fragments requires fragment factory 'R ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. ~~ -!!! error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +!!! error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.

text
diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt index 7f6fff30ca667..8f49a100fa7ef 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt @@ -1,5 +1,5 @@ preact.tsx(3,11): error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. -preact.tsx(3,11): error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +preact.tsx(3,11): error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ==== react.tsx (0 errors) ==== @@ -20,7 +20,7 @@ preact.tsx(3,11): error TS6876: Using JSX fragments requires fragment factory 'R ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. ~~ -!!! error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +!!! error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.

text
diff --git a/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt b/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt index e486b48902f53..34d323737f4a3 100644 --- a/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt +++ b/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt @@ -1,5 +1,5 @@ index.js(2,12): error TS17014: JSX fragment has no corresponding closing tag. -index.js(2,13): error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +index.js(2,13): error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. index.js(2,13): error TS17004: Cannot use JSX unless the '--jsx' flag is provided. index.js(3,1): error TS1005: ''}` or `>`? @@ -14,7 +14,7 @@ index.tsx(6,1): error TS1005: ' x; ~~ -!!! error TS6876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +!!! error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ~~ !!! error TS17014: JSX fragment has no corresponding closing tag. const c = + <1234> x; From af563320cbe47fac21402e1a9206eea5154a9b44 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Thu, 26 Sep 2024 16:04:46 -0700 Subject: [PATCH 15/16] remove unused nodelinks property --- src/compiler/types.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 16cc8266e651b..b45a9bb276552 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6212,7 +6212,6 @@ export interface NodeLinks { resolvedType?: Type; // Cached type of type node resolvedSignature?: Signature; // Cached signature of signature node or call expression resolvedSymbol?: Symbol; // Cached name resolution result - resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result effectsSignature?: Signature; // Signature with possible control flow effects enumMemberValue?: EvaluatorResult; // Constant value of enum member isVisible?: boolean; // Is this node visible From b850aac1316da856fc85c885b1ac9a79c90db7d6 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Fri, 27 Sep 2024 14:56:14 -0700 Subject: [PATCH 16/16] error number merge conflcit --- .../reference/inlineJsxAndJsxFragPragma.errors.txt | 12 ++++++------ ...dJsxFragPragmaOverridesCompilerOptions.errors.txt | 4 ++-- .../inlineJsxFactoryWithFragmentIsError.errors.txt | 4 ++-- .../jsxFactoryAndJsxFragmentFactoryNull.errors.txt | 4 ++-- ...jsTransformCustomImport(jsx=react-jsx).errors.txt | 4 ++-- ...ransformCustomImport(jsx=react-jsxdev).errors.txt | 4 ++-- ...sformCustomImportPragma(jsx=react-jsx).errors.txt | 4 ++-- ...rmCustomImportPragma(jsx=react-jsxdev).errors.txt | 4 ++-- ...seUnaryExpressionNoTypeAssertionInJsx2.errors.txt | 4 ++-- ...seUnaryExpressionNoTypeAssertionInJsx4.errors.txt | 4 ++-- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt b/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt index 422e343f36a69..6dd5e9c1454eb 100644 --- a/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt +++ b/tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt @@ -1,9 +1,9 @@ preacty-no-fragment.tsx(5,12): error TS6133: 'Fragment' is declared but its value is never read. preacty-only-fragment-no-jsx.tsx(6,1): error TS2874: This JSX tag requires 'h' to be in scope, but it could not be found. snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2874: This JSX tag requires 'jsx' to be in scope, but it could not be found. -snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. -snabbdomy-only-fragment.tsx(4,1): error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. -snabbdomy.tsx(4,1): error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +snabbdomy-only-fragment-no-jsx.tsx(4,1): error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +snabbdomy-only-fragment.tsx(4,1): error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +snabbdomy.tsx(4,1): error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== renderer.d.ts (0 errors) ==== @@ -32,7 +32,7 @@ snabbdomy.tsx(4,1): error TS2876: Using JSX fragments requires fragment factory import {jsx} from "./renderer"; <> ~~ -!!! error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +!!! error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== preacty-only-fragment.tsx (0 errors) ==== /** @@ -48,7 +48,7 @@ snabbdomy.tsx(4,1): error TS2876: Using JSX fragments requires fragment factory import {jsx} from "./renderer"; <> ~~ -!!! error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +!!! error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== preacty-only-fragment-no-jsx.tsx (1 errors) ==== /** @@ -68,7 +68,7 @@ snabbdomy.tsx(4,1): error TS2876: Using JSX fragments requires fragment factory ~~ !!! error TS2874: This JSX tag requires 'jsx' to be in scope, but it could not be found. ~~ -!!! error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +!!! error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== preacty-no-fragment.tsx (1 errors) ==== /** diff --git a/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt b/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt index c21a12381f72d..19ba24340e2da 100644 --- a/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt +++ b/tests/baselines/reference/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.errors.txt @@ -1,4 +1,4 @@ -snabbdomy.tsx(6,1): error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +snabbdomy.tsx(6,1): error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== react.d.ts (0 errors) ==== @@ -39,7 +39,7 @@ snabbdomy.tsx(6,1): error TS2876: Using JSX fragments requires fragment factory import {h} from "./snabbdom"; <>
~~ -!!! error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +!!! error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== mix-n-match.tsx (0 errors) ==== /* @jsx h */ diff --git a/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt b/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt index 403b841c71d26..5bddd259ed823 100644 --- a/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt +++ b/tests/baselines/reference/inlineJsxFactoryWithFragmentIsError.errors.txt @@ -1,5 +1,5 @@ index.tsx(3,1): error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found. -index.tsx(3,1): error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +index.tsx(3,1): error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. index.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. reacty.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. @@ -27,6 +27,6 @@ reacty.tsx(3,1): error TS17017: An @jsxFrag pragma is required when using an @js ~~ !!! error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found. ~~ -!!! error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +!!! error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ~~~~~~~~~~~~ !!! error TS17017: An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments. \ No newline at end of file diff --git a/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt index 2804285fca3a2..df7d2e819b46c 100644 --- a/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt +++ b/tests/baselines/reference/jsxFactoryAndJsxFragmentFactoryNull.errors.txt @@ -1,4 +1,4 @@ -jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. ==== jsxFactoryAndJsxFragmentFactoryNull.tsx (1 errors) ==== @@ -6,5 +6,5 @@ jsxFactoryAndJsxFragmentFactoryNull.tsx(3,1): error TS2876: Using JSX fragments <>; ~~ -!!! error TS2876: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. +!!! error TS2879: Using JSX fragments requires fragment factory 'null' to be in scope, but it could not be found. <>1<>2.12.2; \ No newline at end of file diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt index caf4fb3f3d654..2b8fbaf4e46f0 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt @@ -1,5 +1,5 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. -jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ==== jsxJsxsCjsTransformCustomImport.tsx (2 errors) ==== @@ -8,7 +8,7 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2876: Using JSX fragments req ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. ~~ -!!! error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +!!! error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.

text
diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt index 1422559073554..31af5093deb3a 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt @@ -1,5 +1,5 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. -jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ==== jsxJsxsCjsTransformCustomImport.tsx (2 errors) ==== @@ -8,7 +8,7 @@ jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2876: Using JSX fragments req ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. ~~ -!!! error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +!!! error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.

text
diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt index 17e403fafb8bf..7155c43a5dad4 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt @@ -1,5 +1,5 @@ preact.tsx(3,11): error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. -preact.tsx(3,11): error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +preact.tsx(3,11): error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ==== react.tsx (0 errors) ==== @@ -20,7 +20,7 @@ preact.tsx(3,11): error TS2876: Using JSX fragments requires fragment factory 'R ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. ~~ -!!! error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +!!! error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.

text
diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt index 8f49a100fa7ef..ad4bb3c20b12a 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt @@ -1,5 +1,5 @@ preact.tsx(3,11): error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. -preact.tsx(3,11): error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +preact.tsx(3,11): error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ==== react.tsx (0 errors) ==== @@ -20,7 +20,7 @@ preact.tsx(3,11): error TS2876: Using JSX fragments requires fragment factory 'R ~~ !!! error TS2875: This JSX tag requires the module path 'preact/jsx-dev-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. ~~ -!!! error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +!!! error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found.

text
diff --git a/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt b/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt index 34d323737f4a3..b4fb215aaed6f 100644 --- a/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt +++ b/tests/baselines/reference/parseUnaryExpressionNoTypeAssertionInJsx2.errors.txt @@ -1,5 +1,5 @@ index.js(2,12): error TS17014: JSX fragment has no corresponding closing tag. -index.js(2,13): error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +index.js(2,13): error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. index.js(2,13): error TS17004: Cannot use JSX unless the '--jsx' flag is provided. index.js(3,1): error TS1005: ''}` or `>`? @@ -14,7 +14,7 @@ index.tsx(6,1): error TS1005: ' x; ~~ -!!! error TS2876: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. +!!! error TS2879: Using JSX fragments requires fragment factory 'React' to be in scope, but it could not be found. ~~ !!! error TS17014: JSX fragment has no corresponding closing tag. const c = + <1234> x;