Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated with explicit children in mind #510

Conversation

eps1lon
Copy link
Member

@eps1lon eps1lon commented Jun 4, 2022

Also ensured that ReactNode children are always optional. They already include undefined so newer TS versions would reject <Component /> but not <Component></Component> which is quite annoying.

Part of #495

@eps1lon eps1lon force-pushed the 06-04-Updated_with_explicit_children branch from 409e889 to 4db5b44 Compare June 4, 2022 11:00
Comment on lines -62 to -67
children1: JSX.Element; // bad, doesnt account for arrays
children2: JSX.Element | JSX.Element[]; // meh, doesn't accept strings
children3: React.ReactChildren; // despite the name, not at all an appropriate type; it is a utility
children4: React.ReactChild[]; // better, accepts array children
children: React.ReactNode; // best, accepts everything (see edge case below)
functionChildren: (name: string) => React.ReactNode; // recommended function as a child render prop type
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no sensible recommendation for render prop type since it depends heavily on what you want to do. The pattern itself is rarely used nowadays so let's not overwhelm people with React patterns at this point.

children1: JSX.Element; // bad, doesnt account for arrays
children2: JSX.Element | JSX.Element[]; // meh, doesn't accept strings
children3: React.ReactChildren; // despite the name, not at all an appropriate type; it is a utility
children4: React.ReactChild[]; // better, accepts array children
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type is deprecated.

@@ -59,12 +59,8 @@ Relevant for components that accept other React components as props.

```tsx
export declare interface AppProps {
children1: JSX.Element; // bad, doesnt account for arrays
children2: JSX.Element | JSX.Element[]; // meh, doesn't accept strings
children3: React.ReactChildren; // despite the name, not at all an appropriate type; it is a utility
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type is deprecated.

@@ -59,12 +59,8 @@ Relevant for components that accept other React components as props.

```tsx
export declare interface AppProps {
children1: JSX.Element; // bad, doesnt account for arrays
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't necessarily mean it's bad. This might be intended.

@@ -68,7 +68,6 @@ function CommentList({ data }: WithDataProps<typeof comments>) {
}
interface BlogPostProps extends WithDataProps<string> {
id: number;
// children: ReactNode;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unclear why this was here. better remove it if it's unused.

@@ -346,79 +346,6 @@ class List<T> extends React.PureComponent<Props<T>, State<T>> {
}
```

### Generic components with children

`children` is usually not defined as a part of the props type. Unless `children` are explicitly defined as a part of the `props` type, an attempt to use `props.children` in JSX or in the function body will fail:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

children now have to be defined explicitly so this section is obsolete.

@eps1lon eps1lon marked this pull request as ready for review June 4, 2022 11:04
@eps1lon eps1lon requested a review from filiptammergard June 4, 2022 11:05
@eps1lon eps1lon force-pushed the 06-04-Updated_with_explicit_children branch from 4db5b44 to 1a6f39f Compare June 4, 2022 11:06
Copy link
Collaborator

@orta orta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Structurally looks good to me

Copy link
Collaborator

@filiptammergard filiptammergard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Not sure I understand why newer TS versions would reject <Component /> but not <Component></Component> though. Can you explain?

@eps1lon
Copy link
Member Author

eps1lon commented Jun 4, 2022

<Component /> has missing children but { children: ReactNode } requires children even if it is explicitly undefined.

<Component></Component> is equivalent to <Component children={undefined} />

https://tkdodo.eu/blog/optional-vs-undefined explains this in more detail

@eps1lon eps1lon merged commit b47c4c1 into typescript-cheatsheets:main Jun 4, 2022
@eps1lon eps1lon deleted the 06-04-Updated_with_explicit_children branch June 4, 2022 13:42
@eps1lon eps1lon mentioned this pull request Jun 9, 2022
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants