I'm working on a Next.js application and trying to fetch post details based on a dynamic route parameter. However, I'm running into a TypeScript error related to params.
Error Message:
.next/types/app/(pages)/blog/[id]/edit/page.ts:34:29
Type error: Type '{ params: { id: string; }; }' does not satisfy the constraint 'PageProps'.
Types of property 'params' are incompatible.
Type '{ id: string; }' is missing the following properties from type 'Promise<any>': then, catch, finally, [Symbol.toStringTag]
32 |
33 | // Check the prop type of the entry function
> 34 | checkFields<Diff<PageProps, FirstArg<TEntry['default']>, 'default'>>()
| ^
35 |
36 | // Check the arguments and return type of the generateMetadata function
37 | if ('generateMetadata' in entry) {
Static worker exited with code: 1 and signal: null
ELIFECYCLE Command failed with exit code 1.
Code Snippet:
import { fetchUserData } from "@actions/user";
import { fetchPostDetail } from "@actions/posts";
import PostDetail from "@/components/posts/PostDetail";
import { getSession } from "@actions/auth";
async function getData(id: string, isLoggedIn: boolean) {
try {
const { data: post } = await fetchPostDetail(id);
let userData = null;
if (isLoggedIn) {
userData = await fetchUserData();
}
return { post, userData };
} catch (error: unknown) {
return { post: null, userData: null, error };
}
}
export default async function BlogPost({
params,
}: {
params: Promise<{ id: string }>;
}) {
const id = (await params).id;
if (!id) {
return <div>Post not found</div>;
}
const session = await getSession();
const isLoggedIn = !!session?.userToken;
const { post, userData, error } = await getData(id, isLoggedIn);
if (error || !post) {
const isServerError = error?.response?.status === 500;
return (
<article className="flex justify-center items-center min-h-screen">
<div className="flex justify-center items-center w-full px-4 sm:px-6 lg:px-8">
<div className="w-full max-w-md rounded-lg shadow-lg p-8 bg-white dark:bg-gray-800">
<h5 className="mb-4 text-3xl font-semibold tracking-tight text-gray-900 dark:text-white text-center">
{isServerError ? "Server Error" : "Post not found"}
</h5>
<p className="text-lg text-gray-600 dark:text-gray-300 text-center">
{isServerError
? "There was an issue fetching the post. Please try again later."
: "It looks like this post is not available at the moment. Please check back later or create new content."}
</p>
</div>
</div>
</article>
);
}
const userId = isLoggedIn && userData?.data ? userData.data.id : "";
return <PostDetail post={post} userId={userId} isLoggedIn={isLoggedIn} />;
}
What I've Tried
Promise<{ id: string }>
to { id: string }
, but it still throws an error.Why is params being treated as a Promise, and how can I properly type it to avoid this TypeScript error in Next.js?
EDIT: See my answer!
I post my answer, beacuse a I think that a lot of people are not aware that from Next.js v15 params attribute is considered as DYNAMIC API which can only be known during request - response lifecycle. That means, params needs to satisfy Promise type and to get params request for a page resource have to be made.
Related resources: