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.
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.
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.
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.
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> }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With