React.ReactNode vs JSX.Element

I never understood what the difference was between the two types in Typescript but got some clarity on the topic, courtesy of Matt Pocock.

JSX.Element is the thing that gets returned when a JSX expression gets evaluated.

React can render JSX.Elements but it can also render other things! You can tell React to render an array and it will work as long as each child element is something React can render. But an array is not a JSX.Element! You can also render strings in React, à la <Component> Heyyyyy </Component>, but strings are also not JSX.Element.

To bundle all the types that React supports, you introduce React.ReactNode. The type definition makes it super clear:

namespace JSX {
  interface Element extends React.ReactElement<any, any> {}
}

declare namespace React {
  type ReactNode =
    | ReactElement
    | string
    | number
    | ReactFragment
    | ReactPortal
    | boolean
    | null
    | undefined;
}