Thorkil Værge
Thorkil Værge

Reputation: 3787

When to use React.PropsWithChildren

In what to me seems like two similar setups, on one machine I was allowed to call

<MyApp
        accountId={this.props.accountId}
        children={toggleButton} />

Where MyApp had the class signature

export interface IMyAppProps {
  accountId: string;
  dispatch: any;
}
    class MyApp extends React.Component<IMyAppProps, IMyAppState> {

On the other machine, running npm run-script build fails with

TypeScript build error TS2322: Type ' ... ' is not assignable to type ' ... '

Property 'children' does not exist on type 'IntrinsicAttributes & Pick<IMyAppProps, "accountId">'

Versions used on both machines react-scripts-ts 4.0.8, typescript 3.4.5.

Changing the class definition to this made it work on both machines

class MyApp extends React.Component<React.PropsWithChildren<IMyAppProps>, IMyAppState> {

I am unsure why it works in one setup and not the other. When do I wrap my props interface in React.PropsWithChildren?

My best guess would be that the change is to be found in a typings file for React or for a React-related package.

Upvotes: 24

Views: 43854

Answers (2)

Jason Kohles
Jason Kohles

Reputation: 804

The actual answer has nothing to do with whether you use <MyApp children={...} or <MyApp><Child /></MyApp>. The difference is that in the first example IMyAppProps does not have a children property defined, so TypeScript complains that you can't use it like that. When you wrap it in WithChildren that adds a children property to the interface.

Upvotes: 2

ChrisW
ChrisW

Reputation: 56113

I don't know why it worked on one machine but not the other but I don't think that's the right way to use the children property.

Instead of this ...

<MyApp
        accountId={this.props.accountId}
        children={toggleButton} />

... I think the purpose of children is to let you call something like this ...

<MyApp accountId={this.props.accountId}>
  <ToggleButton/>
</MyApp>

... or something like that.

The child or children -- <ToggleButton/> in my example above -- might be a React element, or text (a text node), or undefined if there is no child, or maybe an expression like {toggleButton} which evaluates to one of the child types.

Upvotes: 12

Related Questions