Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I restrict the type of React Children in TypeScript, using the newly added support in TypeScript 2.3?

I'm trying to take advantage of the recently added support for typing of children in the TypeScript compiler and @types/react, but struggling. I'm using TypeScript version 2.3.4.

Say I have code like this:

interface TabbedViewProps {children?: Tab[]} export class TabbedView extends React.Component<TabbedViewProps, undefined> {    render(): JSX.Element {     return <div>TabbedView</div>;   } }  interface TabProps {name: string} export class Tab extends React.Component<TabProps, undefined> {   render(): JSX.Element {     return <div>Tab</div>   } } 

When I try to use these components like so:

return <TabbedView>   <Tab name="Creatures">     <div>Creatures!</div>   </Tab>   <Tab name="Combat">     <div>Combat!</div>   </Tab> </TabbedView>; 

I get an error as follows:

ERROR in ./src/typescript/PlayerView.tsx (27,12): error TS2322: Type '{ children: Element[]; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<TabbedView> & Readonly<{ children?: ReactNode; }> ...'.   Type '{ children: Element[]; }' is not assignable to type 'Readonly<TabbedViewProps>'.     Types of property 'children' are incompatible.       Type 'Element[]' is not assignable to type 'Tab[] | undefined'.         Type 'Element[]' is not assignable to type 'Tab[]'.           Type 'Element' is not assignable to type 'Tab'.             Property 'render' is missing in type 'Element'. 

It seems to be inferring the type of children as just Element[] instead of Tab[] even though that's the only type of children I'm using.

EDIT: It would also be fine to restrict the interface of the children props instead of restricting the type of the children components directly, since all I need to do is pull some specific props out of the children components.

like image 229
Christopher Armstrong Avatar asked Jun 10 '17 15:06

Christopher Armstrong


People also ask

What is the typescript type for React children?

Using React children props with Typescript Typescript is a type-strict JavaScript library, which means you must define the types for your React children props, and there are different methods of declaring types for React children props.

What do you use to avoid adding additional nodes in React?

Use [], instead of ()'s to wrap the entire return. Show activity on this post. Show activity on this post. This is still required, BUT React now make sure to create elements without creating an additional DOM element.

What does React children toArray do?

Children. toArray. Returns the children opaque data structure as a flat array with keys assigned to each child. Useful if you want to manipulate collections of children in your render methods, especially if you want to reorder or slice this.


1 Answers

Edit 2: Turns out that this approach prevent the warning, but according to the comments TabProps aren't properly checked.

You should try to set children of interface TabbedViewProps like so

interface TabbedViewProps { children?: React.ReactElement<TabProps>[] } 

The idea here is not to tell your TabbedView has an array of Tab, but instead tell your TabbedView he has an array of element which takes specific props. In your case TabProps.

Edit ( thx to Matei ):

interface TabbedViewProps {     children?: React.ReactElement<TabProps>[] | React.ReactElement<TabProps> } 
like image 194
Pierre Ferry Avatar answered Oct 06 '22 20:10

Pierre Ferry