Reputation: 467
I'm having this error output in my react project
TypeScript error
Argument of type 'ReactNode' is not assignable to parameter of type 'ReactElement<any, string | JSXElementConstructor<any>> | ReactElement<any, string | JSXElementConstructor<any>>[]'.
Type 'undefined' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>> | ReactElement<any, string | JSXElementConstructor<any>>[]'.
But I can't find out exactly what's wrong with my code, here's:
const { children } = props;
> 19 | const mapChildren = React.Children.map(children, (tread: ReactElement) => tread);
| ^
20 | const child = mapChildren.filter((tread: ReactElement) => tread.props.id === currentTread)[0];
21 |
22 | useEffect(() => {
init(mapChildren);
}, []);
What exactly is wrong with the children element?
Upvotes: 0
Views: 2126
Reputation: 576
This is sufficient and type-safe:
const mapChildren = React.Children.map(children, (tread) => tread);
The type of tread
is prescribed by Children.map
and inferred by TypeScript.
Nothing is wrong with children
as such.
But we have to ensure that the type of children
matches the type of the function passed to Children.map
:
map<T, C>(
children: C | C[],
fn: (child: C, index: number) => T
): C extends null | undefined
? C
: Array<Exclude<T, boolean | null | undefined>>;
(Source)
This means that the type of the child
argument of fn
has to be the same as the type of children
(regardless of whether children
is a single object or an array).
(tread: ReactElement) => tread
as fn
?We're saying that fn
will only accept children that are ReactElement
s.
However, children
are ReactNode
s (unless you explicitly type it differently), so React can't pass them through fn
because of the type mismatch.
ReactElement
is just one of several possible types of ReactNode
:
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined
type ReactChild = ReactElement | ReactText
undefined
is not assignable to ReactElement
)?The error means "A child might be of type undefined
but the function you passed to map
won't accept that."
undefined
is the last type in the definition of ReactNode
and in union types, that's (apparently) what TypeScript does – only complains about the last incompatible type.
Upvotes: 2