Reputation: 7752
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.
Upvotes: 4
Views: 4827
Reputation: 31
Your function is returning a React.FC type, which shouldnt be the case. The return type of function components is ReactNode, plus children are implicitly provided by the React.FC typing. If you explicitly type them, you can omit the React.FC and write:
const SiteLayout = ({children}: Props) => {
return (
<div>
{children}
</div>
)
}
Upvotes: 0
Reputation: 37948
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.
Upvotes: 7