What is the correct typescript type for react children?
Asked Answered
I

4

20

I'm trying to properly type the props for a component that maps children:

type Props = {
    children: any
}

const MyComponent: FunctionComponent<Props> = () => (React.Children.map(children, someMapingFunction);

I've been using JSX.Element but that doesn't quite feel right.

Insidious answered 15/4, 2020 at 18:58 Comment(2)
I use React.ReactNodeMessmate
Are you trying to type your children to a specific controlled type? If not, you should probably use React.PropsWithChildren<MyProps>. That adds the default children to any props.Millar
I
36

Looking through the code under DefinitelyTyped it appears that children is typed as ReactNode.

Example:

type Props = {
    children: ReactNode
}

const MyComponent: FunctionComponent<Props> = () => (React.Children.map(children, someMapingFunction);

Note: The ReactNode type can be found in the React namespace:

import React from 'react';

let someNode: React.ReactNode;
Insidious answered 15/4, 2020 at 19:13 Comment(1)
And if the component takes children optionally, then children?: React.ReactNode is the right type.Rebekah
A
1

The children is a prop like any other and can be of any type. It's only special insofar that child JSX elements are automatically mapped to the children prop.

So, while it's usually declared as children?: React.ReactNode, you could declare it as a render prop, or even as a custom type like so:

interface INameProps {
    children: {
        fistName: string,
        lastName: string
    }
}

const Name: React.FC<INameProps> = ({children}) => {
    return <div>{children.fistName} {children.lastName}</div>;
}

And then you can use it like so:

<Name>
    {
        {
            fistName: "John",
            lastName: "Smith"
        }
    }
</Name>

Which is the same as:

<Name
    children={
        {
            fistName: "John",
            lastName: "Smith"
        }
    }
/>
Accompaniment answered 21/4, 2022 at 7:16 Comment(0)
C
0

Actually you don't have to specify children if you're using React.FunctionComponent.

For example the following codes compile without error:

const MyComponent: React.FC<{}> = props => {
  return props.children
}
Conall answered 16/4, 2020 at 5:11 Comment(3)
I know that you don't need to. For completeness I like to specify children on the props for components that take children.Insidious
This is no longer the case with React 18 - children were removed from Raact.FC (which is now the same as React.VFC) and so you need to declare them explicitly.Accompaniment
So with React 18, how should they be typed for a wrapper of render with a redux store?Burbage
D
0

It's not ReactNode but ReactElement<any, any> | null.

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e90f1299270f6d602fa1af074fb5b3b088c53c09/types/react/index.d.ts#L511

    interface FunctionComponent<P = {}> {
        (props: P, context?: any): ReactElement<any, any> | null;
        propTypes?: WeakValidationMap<P> | undefined;
        contextTypes?: ValidationMap<any> | undefined;
        defaultProps?: Partial<P> | undefined;
        displayName?: string | undefined;
    }
Dispersion answered 8/4, 2022 at 16:21 Comment(3)
using any turns off typechecking, thus usually no good practice..Adorn
You can send a PR to react types to consider changing that. But currently this is the exact type react uses, see the link.Dispersion
that doesn't look like type of children prop, it's the type a FunctionComponent is expected to return? Type of props.children depends on P type parameter, but is not constrained here by default.Weismann

© 2022 - 2024 — McMap. All rights reserved.