How to restrict React Children type in TypeScript using recently added support in TypeScript 2.3?

I am trying to use recently added support for typing children in the TypeScript compiler and @ type / react, but it is struggling. I am using TypeScript version 2.3.4.

Let's say I have this code:

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 as follows:

 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 output the type of children as soon as Element[] instead of Tab[] , although this is the only type of children that I use.

EDIT: It would also be nice to restrict the props interface for children, rather than restricting the type of child components directly, since all I need to do is pull some specific details from the child components.

+20
reactjs typescript
source share
2 answers

You should try setting the children of the TabbedViewProps interface as follows

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

The idea here is not to say that your TabbedView has a Tab array, but instead to tell your TabbedView it has an element array that takes certain details. In your case, TabProps .

Edit (thanks Matey):

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

Edit 2: It turns out that this approach prevents the warning, but according to the comments, TabProps not checked properly.

+12
source share

The type returned in the tab display method is JSX.Element. This is the cause of your problem. TabbedView expects an array of children of type Tab. I'm not sure if you can specify a specific component as a type of children. It can be a string or JSX.Element. Can you show the definition file for Tab?

Check out https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts to see what the JSX.Element interface looks like.

-2
source share

All Articles