I would like to only allow specific components as children. For example, let's say I have a Menu component, that should only contain MenuItem
as children, like this:
<Menu>
<MenuItem />
<MenuItem />
</Menu>
So I would like Typescript to throw me an error in the IDE when I try to put another component as child. Something warning me that I should only use MenuItem
as children. For example in this situation:
<Menu>
<div>My item</div>
<div>My item</div>
</Menu>
This thread is almost similar but does not include a TypeScript solution. I was wondering if the problem can be solved using TypeScript types and interfaces. In my imaginary world it would look like this, but of course the type checking is not working because the child component has an Element
type:
type MenuItemType = typeof MenuItem;
interface IMenu {
children: MenuItemType[];
}
const MenuItem: React.FunctionComponent<IMenuItem> = ({ props }) => {
return (...)
}
const Menu: React.FunctionComponent<IMenu> = ({ props }) => {
return (
<nav>
{props.children}
</nav>
)
}
const App: React.FunctionComponent<IApp> = ({ props }) => {
return (
<Menu>
<MenuItem />
<MenuItem />
</Menu>
)
}
Is there a way to achieve this with Typescript? Like to extend the Element type with something related only to a specific component?
Or what would be a good approach for being sure that a child is an instance of a specific component? Without having to add condition that looks at the child component displayName.
By invoking them between the opening and closing tags of a JSX element, you can use React children for entering data into a component. The React children prop is an important concept for creating reusable components because it allows components to be constructed together.
You can pass a component as props in React by using the built-in children prop. All elements you pass between the opening and closing tags of a component get assigned to the children prop.
React Components and Children In React, a component can have one, many, or no children.
props. children }. The important thing to note here is that children are a special prop that is used to pass the data from the parent component to the children component but this data must be enclosed within the parent's opening and closing tag.
To do that you need to extract props interface from children component (and preferably also parent) and use it this way:
interface ParentProps {
children: ReactElement<ChildrenProps> | Array<ReactElement<ChildrenProps>>;
}
so in your case it would look like this:
interface IMenu {
children: ReactElement<IMenuItem> | Array<ReactElement<IMenuItem>>;
}
const MenuItem: React.FunctionComponent<IMenuItem> = ({ props }) => {
return (...)
}
const Menu: React.FunctionComponent<IMenu> = ({ props }) => {
return (
<nav>
{props.children}
</nav>
)
}
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