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.