TypeScript and Children
What happens when we pass in children in React? Children is a special prop that allows us to pass in any type of element. It could be a number, a string, a boolean, an array of elements or even another component. So how can we check the types?
Of course we could define it as any which is basically the same as just not having type checking which defeats the whole purpose of using Typescript.
There are a couple of types we could choose from:
JSX.Element
Children must be a single JSX element. Doesn't allow multiple children, or strings etc.
interface ButtonProps { children: JSX.Element}const Button = ({ children }: ButtonProps) => <button>{children}</button>export function Card() { return ( <Button> <span>Click me</span> </Button> )}
JSX.Element
Allows multiple JSX elements but no strings, numbers etc
interface ButtonProps { children: JSX.Element[]}const Button = ({ children }: ButtonProps) => <button>{children}</button>export default function Card() { return ( <Button> <span>click me</span> <i>svg icon</i> </Button> )}
JSX.Element | JSX.Element
Allows single or multiple JSX elements but no strings, numbers etc
interface ButtonProps { children: JSX.Element | JSX.Element[]}const Button = ({ children }: ButtonProps) => <button>{children}</button>export function Card() { return ( <Button> <span>click me</span> </Button> )}export function Card2() { return ( <Button> <span>click me</span> <i>svg icon</i> </Button> )}
React.ReactChild
Allows one React element, string or number
interface ButtonProps { children: React.ReactChild}const Button = ({ children }: ButtonProps) => <button>{children}</button>export default function Card() { return <Button>click me</Button>}
React.ReactChild
Allows multiple React elements, strings or numbers
interface ButtonProps { children: React.ReactChild}const Button = ({ children }: ButtonProps) => <button>{children}</button>export default function Card() { return ( <Button> click me <i>svg icon</i> </Button> )}
React.ReactChild | React.ReactChild
Allows single or multiple React elements, strings or numbers
interface ButtonProps { children: React.ReactChild}const Button = ({ children }: ButtonProps) => <button>{children}</button>export function Card() { return <Button>click me</Button>}export function Card2() { return ( <Button> click me <i>svg icon</i> </Button> )}
React.ReactNode
Allows multiple children, strings, numbers, fragments, portals... We could use the above example but it is a little verbose and ReactNode covers a little more.
interface ButtonProps { children: React.ReactNode}const Button = ({ children }: ButtonProps) => <button>{children}</button>export default function Card() { return ( <Button> click me <i>svg icon</i> </Button> )}
Conclusion
And that's it, you now have no excuses for adding type checking for your children.