next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Next 13: Missing Types for generateStaticParams

Open sdorra opened this issue 2 years ago β€’ 1 comments

Verify canary release

  • [X] I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Version 21.6.0: Mon Aug 22 20:19:52 PDT 2022; root:xnu-8020.140.49~2/RELEASE_ARM64_T6000 Binaries: Node: 16.18.0 npm: 8.19.2 Yarn: 1.22.19 pnpm: 7.13.4 Relevant packages: next: 13.0.0 eslint-config-next: 13.0.0 react: 18.2.0 react-dom: 18.2.0

What browser are you using? (if relevant)

Chrome

How are you deploying your application? (if relevant)

No response

Describe the Bug

A next 13 app with typescript and generateStaticParams can not be build. The following code works in dev mode, but fails on build:

import { use } from "react";
import { fetchPeople, fetchPeoples } from "../../../lib/people";

type Params = {
  id: string;
};

type Props = {
  params: Params;
};

const People = ({ params }: Props) => {
  const people = use(fetchPeople(params.id));
  return (
    <>
      <h1>{people.name}</h1>
    </>
  );
};

export const generateStaticParams = async (): Promise<Params[]> => {
  const peoples = await fetchPeoples();

  const result = peoples.map((people) => ({
    id: people.id,
  }));

  return result;
}

export default People;

The build fails with the following error:

Type error: Page "app/people/[id]/page.tsx" does not match the required types of a Next.js Page.
  Invalid configuration:
    The exported page component isn't correctly typed.
        Expected "Props", got "PageProps".
          Invalid configuration:
            Expected "Params", got "PageParams | undefined".
              Expected "Params", got "undefined".

Sadly i was not able to find the mentioned types of the error.

Have a look at the following discussions for more informations:

  • https://github.com/vercel/next.js/discussions/41826#discussioncomment-3966869
  • https://github.com/vercel/next.js/discussions/41745#discussioncomment-3971314

Expected Behavior

The example above can be build or the required types are exported.

Link to reproduction

https://github.com/sdorra/next-13-missing-types

To Reproduce

Run pnpm build in the example repository

sdorra avatar Oct 26 '22 18:10 sdorra

I'm facing the same problem during build:

type PageParams = {
  slug: string;
};

type PageProps = {
  params: PageParams;
};

export const dynamicParams = true;

export async function generateStaticParams(): Promise<PageParams[]> {
  const payload = await getNodes();

  return payload.nodes.map((node) => ({
    slug: node.path
  }));
}

export default async function NodePage({ params }: PageProps) {
  const node = await getNode(params.slug);
  if (!node) return notFound();
  return (
    <div>
      <h1>Hello, Next.js! {params.slug}</h1>
      <pre>{JSON.stringify({ node }, null, 2)}</pre>
    </div>
  );
}
...
info  - Compiled successfully
info  - Linting and checking validity of types ...Failed to compile.

Type error: Page "app/[slug]/page.tsx" does not match the required types of a Next.js Page.
  Invalid configuration:
    The exported page component isn't correctly typed.
          Invalid configuration:
            Expected "{ slug: string; } | undefined", got "PageParams | undefined".

czterystaczwarty avatar Oct 26 '22 22:10 czterystaczwarty

Same here

export async function generateStaticParams() {
  const client = getClient();
  const res = await client.fetch(getArticlesSlugQuery);
  const articles = z.array(z.object({ slug: z.string() })).parse(res);

  return articles.map((article) => ({
    slug: article.slug,
  }));
}

export default async function Page({ params }: {
  params: { slug: string },
}) {

  // Queue up the promises here...
  const _article = getArticle(params.slug);
  const _relatedArticles = getRelatedArticles(params.slug);

  const article = await _article;

  return (
    <div>
      <div className='grid gap-x-20 grid-cols-[minmax(68ch,_1fr)_1fr] lg:items-start'>
        <article className='prose lg:text-lg'>
          <h1>{article.title}</h1>
          <RichText content={article.content} />
        </article>
        <aside className='sticky top-4'>
          <TableOfContent headings={article.tableOfContents} />
        </aside>
      </div>
      {/* Load related articles later on */}
      <Suspense fallback={<p>Loading related articles…</p>}>
        <RelatedArticles promise={_relatedArticles} />
      </Suspense>
    </div>
  );
}
warn  - You have enabled experimental feature (appDir) in next.config.js.
warn  - Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.
info  - Thank you for testing `appDir` please leave your feedback at https://nextjs.link/app-feedback

info  - Creating an optimized production build
info  - Compiled successfully
info  - Linting and checking validity of types ...Failed to compile.

Type error: Page "app/article/[slug]/page.tsx" does not match the required types of a Next.js Page.
  Invalid configuration:
    The exported page component isn't correctly typed.
        Expected "{ params: { slug: string; }; }", got "PageProps".
          Invalid configuration:
            Expected "{ slug: string; }", got "PageParams | undefined".
              Expected "{ slug: string; }", got "undefined".

patrickedqvist avatar Oct 27 '22 20:10 patrickedqvist

@shuding Any idea when this will be released?

gabrielgrover avatar Oct 31 '22 23:10 gabrielgrover

@gabrielgrover We already released 13.0.1, let us know if the issue is still happening!

shuding avatar Oct 31 '22 23:10 shuding

@shuding I still seem to be getting this error. Here is the result of running next build

Screen Shot 2022-10-31 at 9 19 19 PM

Here is the file it is failing at https://github.com/gabrielgrover/improved-octo-spoon/blob/main/app/blog/%5Bslug%5D/page.tsx

gabrielgrover avatar Nov 01 '22 04:11 gabrielgrover

After updating to 13.0.1, I was still facing the issue. However, I fixed it by updating the page's type from NextPage to FC.

iAmmar7 avatar Nov 01 '22 08:11 iAmmar7

After updating to 13.0.1, I was still facing the issue. However, I fixed it by updating the page's type from NextPage to FC.

This won't work for me because my blog page is async

gabrielgrover avatar Nov 01 '22 20:11 gabrielgrover

@shuding Any news on this? This is preventing me from deploying.

gabrielgrover avatar Nov 02 '22 15:11 gabrielgrover

I know it's not a good way. However, I typed page props as below, then build was success.

export default async function PostPage({ params }: { params: { slug: string } }) { ... }

KushibikiMashu avatar Nov 06 '22 06:11 KushibikiMashu

I know it's not a good way. However, I typed page props as below, then build was success.

export default async function PostPage({ params }: { params: { slug: string } }) { ... }

can u try typing with searchParams as well?

daveteu avatar Nov 09 '22 08:11 daveteu

I was seeing this error too. My mistake was exporting generateStaticParams without the async keyword.

samstr avatar Nov 12 '22 15:11 samstr

searchParams also has a same problem. please fix this!

export default function Page({searchParams}: { searchParams: { q: string } }) {
    return <>
...

Type error: Page "app/page.tsx" does not match the required types of a Next.js Page.
--
09:39:17.429 | Invalid configuration:
09:39:17.429 | The exported page component isn't correctly typed.
09:39:17.433 | Expected "{ searchParams: { q: string; }; }", got "PageProps".

hyunjunian avatar Nov 16 '22 01:11 hyunjunian

I'm still running into this in 13.0.3. If anybody else stumbles on this, using FC also did the trick for me as a work around as a work-around. With new app folder, a page at app/cameras/[id]/page.tsx and app/cameras/page.tsx both get the same type error:

Type error: Page "app/cameras/page.tsx" does not match the required types of a Next.js Page.
  Invalid configuration:
    The exported page component isn't correctly typed.
      The exported page component isn't correctly typed.

In case it helps anybody else, this was my original code

import type { NextPage } from 'next'

type PageProps = {
  params?: {
    id: string
  }
  searchParams?: {
    search?: string
  }
};

const Home: FC = ({ params }: PageProps) => {
  // render stuff here
})

export default Home

It now works after making these changes:

import { FC } from "react";

type PageProps = {
  params?: {
    id: string
  }
  searchParams?: {
    search?: string
  }
};

const Home: FC = ({ params }: PageProps) => {
  // render stuff here
})

export default Home

fizzterious avatar Nov 16 '22 18:11 fizzterious

I'm currently running "next": "^13.0.3" and i still facing same issue when executing npm run build. this line of code cause the build to fail:

export default async function RoomDashboard({
  searchParams,
}: {
  searchParams: { currentPage: number };
}) {
   // page logic
}

This is the error when executing npm run build:

Type error: Page "app/room/page.tsx" does not match the required types of a Next.js Page.
  Invalid configuration:
    The exported page component isn't correctly typed.
        Expected "{ searchParams: { currentPage: number; }; }", got "PageProps".

I didn't face any problem during dev(npm run dev), I'm not sure whether it's my fault or the feature got some bugs during build time.

NextJS 13 is dope πŸš€ , but there is something can be polish. thank you Nextjs Dev member have a nice day πŸ˜„. I really hope this can be sort out soon..

thaddeuscleo avatar Nov 17 '22 12:11 thaddeuscleo

@thaddeuscleo I have got it now: params and if necessary searchParams must be declared as optional, then the compiler does not complain anymore.

-  searchParams: { currentPage: number };
+  searchParams?: { currentPage: number };

With it also own separately declared props types work.

pmb0 avatar Nov 27 '22 10:11 pmb0

I use this: types/next.ts:

import { Form } from "./forms"

export declare type Params<P> = { [key in keyof P]: string }
export declare type PageProps<
    P extends Params<P>,
    SP extends Params<SP>
> = {
    params: P
    searchParams: SP
}
export declare type SearchParamsSubmittedViaForm<
    T extends Form<HTMLFormControlsCollection>,
    E = Extract<T["elements"], HTMLFormControlsCollection>,
> = Params<Omit<{
    [key in keyof E]: E[key] extends HTMLInputElement ? E[key] : never
}, keyof HTMLFormControlsCollection>>
export declare type HeadProps<P extends Params<P>> = Pick<PageProps<P, never>, 'params'>
export declare type GenerateStaticParams<P extends Params<P>> = () => Promise<P[]>

types/forms.ts:

export declare interface Form<T extends HTMLFormControlsCollection> extends HTMLFormElement {
    readonly elements: T
}
declare interface SearchFormElements extends HTMLFormControlsCollection {
    q: HTMLInputElement
}
export declare type SearchForm = Form<SearchFormElements>

search/[slug]/layout.ts:

import { GenerateStaticParams, Params } from "../../../types/next"

export declare type SearchPageParams = Params<{
    slug: string
}>

export const generateStaticParams: GenerateStaticParams<SearchPageParams> = async () => {
    return AllSearchTypes.map((value, index) => {
        return { slug: value.name }
    })
}

const Layout: React.FC<React.PropsWithChildren> = ({ children }) => <>{children}</>

export default Layout

search/[slug]/page.tsx:

import { PageProps, SearchParamsSubmittedViaForm } from "../../../types/next"
import { SearchPageParams } from "./layout"
import { SearchForm } from "../../../types/search"

const SearchPage = ({params, searchParams}: PageProps<SearchPageParams, SearchParamsSubmittedViaForm<SearchForm>>) => {
    console.log(params)
    console.log(searchParams)
}

export default SearchPage

search/[slug]/head.tsx:

import { HeadProps } from "../../../types/next";
import { SearchPageParams } from "./layout";

const Head = ({params}: HeadProps<SearchPageParams>) => {
    const {slug} = params
    return (
        <>
            <title>{`Support Console - Search ${slug}`}</title>
        </>
    );
}

export default Head
{slug: 'project'}
{q: '%'}
support-console-nextjs:build: β”” ● /search/[slug]                         142 B          66.7 kB
support-console-nextjs:build:     β”œ /search/user
support-console-nextjs:build:     β”œ /search/project
support-console-nextjs:build:     β”œ /search/service
support-console-nextjs:build:     β”” /search/node

Doesn't appear to be any compiler errors and the types are visible.

NotoriousPyro avatar Dec 13 '22 14:12 NotoriousPyro

@pmb0 is spot on. I experience the same error and all I had to do was use the optional chaining operator. The error from @sdorra console explains this as well.

olowoseun avatar Dec 17 '22 01:12 olowoseun

I found this error also occurs when you use NextPage type.

const Page: NextPage = () => {.....

fixed this after I remove or change this type like React.FC.

SANDAY-JS avatar Jan 15 '23 09:01 SANDAY-JS

This is still happening for me on Next 13.1.4, only during next build:

Type error: Page "app/[username]/[storySlug]/page.js" does not match the required types of a Next.js Page.
  Invalid configuration:
    The exported Page component isn't correctly typed.
        Expected "{ params: any; searchParams: any; }", got "PageProps".

app/[username]/[storySlug]/page.js

async function StoryPage({ params, searchParams }) {
  ...
}

export default StoryPage;

Changing it to the following causes the error to not happen:

app/[username]/[storySlug]/page.js

async function StoryPage(props) {
  const { params, searchParams } = props;
  ...
}

export default StoryPage;

mpereira avatar Jan 21 '23 15:01 mpereira

This is still happening for me on Next 13.1.4, only during next build:

Type error: Page "app/[username]/[storySlug]/page.js" does not match the required types of a Next.js Page.
  Invalid configuration:
    The exported Page component isn't correctly typed.
        Expected "{ params: any; searchParams: any; }", got "PageProps".

app/[username]/[storySlug]/page.js

async function StoryPage({ params, searchParams }) {
  ...
}

export default StoryPage;

Changing it to the following causes the error to not happen:

app/[username]/[storySlug]/page.js

async function StoryPage(props) {
  const { params, searchParams } = props;
  ...
}

export default StoryPage;

the perfect fix It worked :) thank you

alsherif-khalaf avatar Jan 27 '23 10:01 alsherif-khalaf

was facing the same error, but my case was wrongly added 'use client' at the top of the page.tsx file, removing this line resolved.

neotan avatar Feb 02 '23 02:02 neotan

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

github-actions[bot] avatar Mar 04 '23 12:03 github-actions[bot]