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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With