Skip to content

Commit

Permalink
Don't create children prop out of non-semantic JSX children (#55981)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist authored Oct 4, 2023
1 parent 6ec5547 commit 274821e
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31261,7 +31261,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// Handle children attribute
const parent = openingLikeElement.parent.kind === SyntaxKind.JsxElement ? openingLikeElement.parent as JsxElement : 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 && parent.children.length > 0) {
if (parent && parent.openingElement === openingLikeElement && getSemanticJsxChildren(parent.children).length > 0) {
const childrenTypes: Type[] = checkJsxChildren(parent, checkMode);

if (!hasSpreadAnyType && jsxChildrenPropertyName && jsxChildrenPropertyName !== "") {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//// [tests/cases/compiler/jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx] ////

//// [jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx]
namespace JSX {
export interface ElementChildrenAttribute {
children: {};
}
}

interface Props {
className?: string | undefined;
}

function NoticeList(props: Props) {
return null;
}

<NoticeList className="my-notice-list">
</NoticeList>;

<NoticeList className="my-notice-list">

</NoticeList>;

//// [jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.jsx]
"use strict";
function NoticeList(props) {
return null;
}
<NoticeList className="my-notice-list">
</NoticeList>;
<NoticeList className="my-notice-list">

</NoticeList>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//// [tests/cases/compiler/jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx] ////

=== jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx ===
namespace JSX {
>JSX : Symbol(JSX, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 0, 0))

export interface ElementChildrenAttribute {
>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 0, 15))

children: {};
>children : Symbol(ElementChildrenAttribute.children, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 1, 45))
}
}

interface Props {
>Props : Symbol(Props, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 4, 1))

className?: string | undefined;
>className : Symbol(Props.className, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 6, 17))
}

function NoticeList(props: Props) {
>NoticeList : Symbol(NoticeList, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 8, 1))
>props : Symbol(props, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 10, 20))
>Props : Symbol(Props, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 4, 1))

return null;
}

<NoticeList className="my-notice-list">
>NoticeList : Symbol(NoticeList, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 8, 1))
>className : Symbol(className, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 14, 11))

</NoticeList>;
>NoticeList : Symbol(NoticeList, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 8, 1))

<NoticeList className="my-notice-list">
>NoticeList : Symbol(NoticeList, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 8, 1))
>className : Symbol(className, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 17, 11))

</NoticeList>;
>NoticeList : Symbol(NoticeList, Decl(jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx, 8, 1))

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//// [tests/cases/compiler/jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx] ////

=== jsxContainsOnlyTriviaWhiteSpacesNotCountedAsChild.tsx ===
namespace JSX {
export interface ElementChildrenAttribute {
children: {};
>children : {}
}
}

interface Props {
className?: string | undefined;
>className : string | undefined
}

function NoticeList(props: Props) {
>NoticeList : (props: Props) => null
>props : Props

return null;
}

<NoticeList className="my-notice-list">
><NoticeList className="my-notice-list"></NoticeList> : error
>NoticeList : (props: Props) => null
>className : string

</NoticeList>;
>NoticeList : (props: Props) => null

<NoticeList className="my-notice-list">
><NoticeList className="my-notice-list"></NoticeList> : error
>NoticeList : (props: Props) => null
>className : string

</NoticeList>;
>NoticeList : (props: Props) => null

Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
jsxEmptyExpressionNotCountedAsChild2.tsx(28,2): error TS2322: Type '{ __children__: never[]; }' is not assignable to type '{ bar?: number | undefined; } & { __children__: () => number; }'.
Type '{ __children__: never[]; }' is not assignable to type '{ __children__: () => number; }'.
Types of property '__children__' are incompatible.
Type 'never[]' is not assignable to type '() => number'.
Type 'never[]' provides no match for the signature '(): number'.
jsxEmptyExpressionNotCountedAsChild2.tsx(28,2): error TS2322: Type '{}' is not assignable to type '{ bar?: number | undefined; } & { __children__: () => number; }'.
Property '__children__' is missing in type '{}' but required in type '{ __children__: () => number; }'.


==== jsxEmptyExpressionNotCountedAsChild2.tsx (1 errors) ====
Expand Down Expand Up @@ -35,9 +32,7 @@ jsxEmptyExpressionNotCountedAsChild2.tsx(28,2): error TS2322: Type '{ __children

<MockComponent>{}</MockComponent>; // error
~~~~~~~~~~~~~
!!! error TS2322: Type '{ __children__: never[]; }' is not assignable to type '{ bar?: number | undefined; } & { __children__: () => number; }'.
!!! error TS2322: Type '{ __children__: never[]; }' is not assignable to type '{ __children__: () => number; }'.
!!! error TS2322: Types of property '__children__' are incompatible.
!!! error TS2322: Type 'never[]' is not assignable to type '() => number'.
!!! error TS2322: Type 'never[]' provides no match for the signature '(): number'.
!!! error TS2322: Type '{}' is not assignable to type '{ bar?: number | undefined; } & { __children__: () => number; }'.
!!! error TS2322: Property '__children__' is missing in type '{}' but required in type '{ __children__: () => number; }'.
!!! related TS2728 jsxEmptyExpressionNotCountedAsChild2.tsx:22:46: '__children__' is declared here.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// @jsx: preserve
// @strict: true

namespace JSX {
export interface ElementChildrenAttribute {
children: {};
}
}

interface Props {
className?: string | undefined;
}

function NoticeList(props: Props) {
return null;
}

<NoticeList className="my-notice-list">
</NoticeList>;

<NoticeList className="my-notice-list">

</NoticeList>;

0 comments on commit 274821e

Please sign in to comment.