8

TS2345: Argument of type 'ReactNode' is not assignable to parameter of type 'ReactElement<any, string | ((props: any) => ReactElement<any, any> | null) | (new (props: any) => Component<any, any, any>)> | ReactElement<any, string | ... 1 more ... | (new (props: any) => Component<...>)>[]'. Type 'undefined' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, any> | null) | (new (props: any) => Component<any, any, any>)> | ReactElement<any, string | ... 1 more ... | (new (props: any) => Component<...>)>[]'.

Image of the error

Here's my code:

import React, {forwardRef, ReactNode} from 'react';

import {mergeClasses} from '../../utils';
import {ArrowLeft} from '../../icons';

import {BreadcrumbsProps} from './declarations/Breadcrumbs.types';

import defaultClasses from './styles/Breadcrumbs.module.css'

export const Breadcrumbs = forwardRef<HTMLLabelElement, BreadcrumbsProps>(
    ({
        separator="/",
        children,
        back,
        classNames,
        onClick,
     }) => {
        const styles = mergeClasses(defaultClasses, classNames);

        const Back = (
            <button className={styles.back} type='button' onClick={onClick}>
                <ArrowLeft/>
                <span>Back</span>
            </button>
        )

        const Separator = <span className={styles.separator}>{separator}</span>;

        const getValidChild = (itemToRender: ReactNode, delta: number, index: number) => {
            const SeparatorWithKey = React.cloneElement(Separator, { key: `${index}_separator` });

            return index === 0 ? [itemToRender] : [SeparatorWithKey, itemToRender];
        };

        const getItemsByChildren = () => {
            const delta = React.Children.toArray(children).length;
            return (
                React.Children.map(children, (child: React.ReactElement, index) => {
                return (
                    child &&
                    getValidChild(
                        React.cloneElement(child),
                        delta,
                        index
                    )
                );
            }));
        };

        return (
            <div className={styles.wrapper}>
                {back && Back}
                <ul className={styles.breadcrumbs}>
                    {getItemsByChildren()}
                </ul>
            </div>
        );
    },
);
Nikita Vitokhin
  • 81
  • 1
  • 1
  • 2

1 Answers1

4

You've declared the type of child wrong here:

React.Children.map(children, (child: React.ReactElement, index) => {

children is of type React.ReactNode. React.Element is something entirely different.

You don't need to type this argument at all, React.Children.map already can infer the correct type here. Just this works just fine:

React.Children.map(children, (child, index) => {

Playground

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337