Reputation: 1738
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.
Upvotes: 7
Views: 9065
Reputation: 8566
To use an async Server Component with TypeScript, ensure you are using TypeScript 5.1.3 or higher and @types/react 18.2.8 or higher.
If you are using an older version of TypeScript, you may see a 'Promise' is not a valid JSX element type error. Updating to the latest version of TypeScript and @types/react should resolve this issue.
next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: { serverActions: true },
};
module.exports = nextConfig;
``
Upvotes: 6
Reputation: 49661
This is a bug. Next.js team has been working on it. You could also use eslint comment
<ClientPage>
// @ts-expect-error Server Component
<ServerPage /> // type error here
</ClientPage>
Upvotes: 0
Reputation: 2613
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.
Warning: You can use async/await in layouts and pages, which are Server Components. Using async/await inside other components, with TypeScript, can cause errors from the response type from JSX. You might see the error 'Promise' is not a valid JSX element. We are tracking this issue here.
Upvotes: 2