I was playing with the experimental Next 13 app
directory.
As per the documents, a client component can accept a server component, as long as it is as a children
prop.
It works, however I do get a type error
‘ServerPage’ cannot be used as a JSX component. Its return type
‘Promise’ is not a valid JSX element.
Type ‘Promise’ is missing the following properties from type ‘ReactElement<any, any>’: type, props, key
import ClientPage from './clientPage';
import ServerPage from './serverPage';
// app/page.tsx
export default function Home() {
// logs in the server
console.log('rendering home page');
return (
<>
<ClientPage>
<ServerPage /> // type error here
</ClientPage>
</>
);
}
the serverPage.tsx component
const fetchSomeData = async () => {
const response = await fetch('https://pokeapi.co/api/v2/pokemon/ditto');
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json();
};
export default async function ServerPage() {
const data = await fetchSomeData();
// this logs in the server
console.log(data);
return (
<>
<main className={styles.main}>
Im a server component
</main>
</>
);
}
the clientPage.tsx component
'use client';
export default function ClientPage({
children,
}: {
children: React.ReactNode;
}) {
// this logs in the client
console.log('rendering client page');
return (
<>
{children}
</>
);
}
I suppose that this has to do with the children type in the clientPage
component, but I’m not sure how this should be typed.
2
Answers
Unfortunately, the only way around this at the moment is to use the
:any
type definition on the async server components.Next.js 13
outlined this in their Typescript documentation.This is a bug. Next.js team has been working on it. You could also use eslint comment