Typescript can't detect props object on children using React.Children.toArray I have to use any[] because if I use ReactChild[] - props is not detected on an array item. How do I correctly type this out? Thanks!
const items: any[] = React.Children.toArray(this.props.children)
// select whatever item was told to be onload first
const itemPaymentType = items[0].props['data-payment']
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.
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.
casieber answer is correct.
but in order to access your props with typescript, this is needed:
const item = items[0];
if (React.isValidElement<{prop1: boolean}>(item)) {
// item.props.prop1 -- works
}
Typescript is doing the right thing here. Take a look at the typings definition for ReactChild:
type ReactChild = ReactElement<any> | ReactText;
where ReactText
is typed as string | number
.
By saying const items: ReactChild[]
you are telling TypeScript that items
is an array that has elements that are possibly strings. Obviously, a string does not have props
as a property, and so it is complaining, rightly so, when you try and use props
.
If you are certain that your component's children will only ever be true elements containing the prop types you are looking for, then you can type the output as ReactElement<P>
where P
is the prop types you expect. However, doing so is essentially casting something that you haven't guaranteed. A better way might be to allow TypeScript type inference to come into play through somethign like the following:
const items = React.Children.toArray(this.props.children); // Will be ReactChild[]
const item = items[0];
if (typeof item === 'string' || typeof item === 'number') {
console.error('Expecting component children to be of type ...');
} else {
// At this point, TypeScript will know that item must be of type ReactElement
// since you have already taken care of the number and string case
const itemPaymentType = item.props['data-payment'];
// ...
}
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