Next.js Discord

Discord Forum

Layout params union types casted to string..

Unanswered
Couch's Kingbird posted this in #help-forum
Open in Discord
Couch's KingbirdOP
Build is failing because next js cast union type to string.

Types of property 'params' are incompatible.
Type 'Promise<{ locale: string; }>' is not assignable to type 'Promise<{ locale: "fr" | "nl" | "en"; }>'.


export const dynamicParams = false;

export async function generateStaticParams(): Promise<{ locale: Locale }[]> {
  return i18n.locales.map((locale) => ({ locale }));
}

export default async function LocaleLayout({children, params}: {
  children: React.ReactNode;
  params: Promise<{ locale: Locale }>;
}) {
  const { locale } = await params;
  const { tr, dict } = await getTranslations(locale);

2 Replies

Couch's KingbirdOP
Thanks for checking. Here's a minimal reproduction:
https://github.com/Tiktak-dev/nextjs-params-error

Created with create-next-app defaults, four files added. npm run build
fails type checking with two errors.

Two things probably explain why it worked for you.

1. It only reproduces with strictFunctionTypes on, which strict: true
implies — and strict: true is the create-next-app default. It makes
parameter types checked contravariantly, so the narrowed Locale union is
rejected. With it off, bivariance accepts the narrowing. On my real project:
7 errors with strict, 4 without, and the 5 that disappear are all layouts.

2. A page declaring the exact same narrowed params produces no error at
all — only layouts do. The generated contracts differ:

default: React.ComponentType<{ params: Promise<ParamMap[Route]> } & any> // AppPageConfig
default: React.ComponentType<LayoutProps<Route>> // LayoutConfig

The page contract is intersected with any, which absorbs any mismatch, so
page params are effectively never validated. Layouts are validated strictly.

That also explains the asymmetry noted in #82820 ("for layouts and routes,
but not for the pages"), which was closed and locked without a cause being
identified.

So if you tested a page, or a project without strict mode, it would look
fine. Could you try the repo with the layout?