Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript checking in React Functional components

I am starting out with TypeScript on a React app (next.js) and I'm not sure how to type React components.

I have a component like...

type Props = {
  children: JSX.Element;
};

export default function SiteLayout({ children }: Props): React.FC {
return (
  <div>
    {children}
  </div>
)

But this gives me the following error:

var children: JSX.Element
Type 'Element' is not assignable to type 'FC<{}>'.
Type 'Element' provides no match for the signature '(props: { children?: ReactNode; }, context?: any): ReactElement<any, any>'.ts(2322)

I also tried to get it working with simply using JSX.Element:

type Props = {
  children: JSX.Element;
};

export default function SiteLayout({ children }: Props): JSX.Element {

return (
  <div>
    {children}
  </div>
)

But this gives the following error in child components.

(alias) function SiteLayout({ children }: Props): JSX.Element import SiteLayout
This JSX tag's 'children' prop expects a single child of type 'Element', but multiple children were provided.ts(2746)

The above component is being consumed in by a Next.js page component like:

import Head from 'next/head';
import SiteLayout, { siteTitle } from '../../components/SiteLayout';

export default function myPage() {
  const pageTitle = 'My Page';


  return (
    <SiteLayout>
      <Head>
        <title>{siteTitle + ' - ' + pageTitle}</title>
      </Head>
      <div>
        content...
      </div>
    </SiteLayout>
  );
}

What is the correct approach? I'm confused when JSX.Element should be used and when React.FC should be.

like image 995
Holly Avatar asked Oct 15 '25 04:10

Holly


1 Answers

The return type of the function is not a component, the function itself is component. That's why instead of

function SiteLayout({ children }: Props): React.FC { ...

It should be:

const SiteLayout: React.FC<Props> = ({ children }: Props) => {
    return (
      <div>
        {children}
      </div>
    );
}

Regarding the type of children prop, if there's no restriction on kind of children (string, boolean, element etc,) better to use ReactNode:

type Props = {
    children: React.ReactNode
}

Here's how it is defined.

like image 121
Aleksey L. Avatar answered Oct 17 '25 22:10

Aleksey L.