I have a component that can accept React children as either a node or an array of nodes. I want to be able to detect if children is an array of nodes, but I am getting the following Typescript error:
TS2339: Property 'length' does not exist on type 'string | number | true | {} | ReactElement<any, string | ((props: any) => ReactElement<any, any> | null) | (new (props: any) => Component<any, any, any>)> | ... 47 more ... | (ReactNode[] & ReactPortal)'. Property 'length' does not exist on type 'number'.
Is there a way in Typescript where I detect if children has length? Thanks.
import React from 'react';
interface Props {
children: React.ReactNode | React.ReactNode[];
}
const SampleComponent: React.FC<Props> = ({ children }) => {
if (children && children.length) {
return children.map((child) => (
<div>{child}</div>
));
}
return children;
};
export default SampleComponent;

There is a React.Children API for dealing with the props.children (which is an opaque data structure).
Also, React.Children has methods like count, map etc.
if (React.Children.count(children)) {
return React.Children.map(children, (child) => <div>{ ..todo.. }</div>)
}
It has TypeScript support too. So, you won't need to cast the types.
[Update]
Please check out Ajeet Shah's response with using React.Children API.
[Original]
Cast children to React.ReactNode[] before checking length like this:
(children as React.ReactNode[]).length
You could also create a type predicate:
https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates
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