Solution
- JSX.Element;: š© This doesn't account for arrays (e.g. multiple elements) at all.
- JSX.Element | JSX.Element[];Ā š This doesn't accept strings.
- React.ReactChildren;: 𤪠Not at even an appropriate type; it's a utility function.
- React.ReactChild[];: š Accepts multiple children, but it doesn't accept a single child.
- React.ReactNode;: š Accepts everything.
This will get everything working as expected:
import React, { ReactNode } from "react";
type BoxProps = { children: ReactNode };
A helpful utility type
This is a pretty simple utility type that you could write yourself, but you don't have to.
type PropsWithChildren<P = unknown> = P & {
  children?: ReactNode | undefined;
};
It's basically an easy way to say, "This component can render children." That's it. This means, we can refactor our example a little more.
import React, { PropsWithChildren } from "react";
const Box = ({ children }: PropsWithChildren) => {
  return (
    <section
      className="m-4"
      style={{ padding: "1em", border: "5px solid purple" }}
    >
      {children}
    </section>
  );
};
What if we wanted to add additional props? We can actually pass PropsWithChildren an argument.
import React, { PropsWithChildren } from "react";
type BoxProps = { color?: "red" | "green" | "blue" };
const Box = ({ children, color = "red" }: PropsWithChildren<BoxProps>) => {
  return (
    <section
      className="m-4"
      style={{ padding: "1em", border: "5px solid purple", color }}
    >
      {children}
    </section>
  );
};
const Application = () => {
  return (
    <main className="m-8">
      <Box color="green">
        Just a string.
        <p>Some HTML that is not nested.</p>
        <Box>
          <h2>Another React component with one child.</h2>
        </Box>
        <Box>
          <h2 className="mb-4">A nested React component with two children.</h2>
          <p>The second child.</p>
        </Box>
      </Box>
    </main>
  );
};
export default Application;
Alternatively, this will work, but the version that I showed you above is standard practice:
const Box = ({ children, color = "red" }: PropsWithChildren & BoxProps) => {
  // ā¦
};
We'll learn how to make our own utility types like this in a bit.