How to pass 'blocking' to getStaticPaths with TypeScript in Next.js?

Viewed 155

I would use fallback: 'blocking', for my Next.js page, but TypeScript refuses it. Has the latest 12.2.0 Next.js. What is wrong?

Type '() => Promise<{ paths: any; fallback: string; }>' is not assignable to type 'GetStaticPaths<ParsedUrlQuery>'.
  Type 'Promise<{ paths: any; fallback: string; }>' is not assignable to type 'GetStaticPathsResult<ParsedUrlQuery> | Promise<GetStaticPathsResult<ParsedUrlQuery>>'.
    Type 'Promise<{ paths: any; fallback: string; }>' is not assignable to type 'Promise<GetStaticPathsResult<ParsedUrlQuery>>'.
      Type '{ paths: any; fallback: string; }' is not assignable to type 'GetStaticPathsResult<ParsedUrlQuery>'.
        Types of property 'fallback' are incompatible.
          Type 'string' is not assignable to type 'boolean | "blocking"'.

and the code:

export const getStaticPaths: GetStaticPaths = async () => {
// ...
    const paths = res.data.map((organizationAndPostId: string) => ({
        params: {
            organizationShortId: organizationAndPostId[0],
            postId: organizationAndPostId[1],
            tempUserShortId: organizationAndPostId[2],
            imgId: organizationAndPostId[3],
        },
    }))

    let ret = {
        paths,
        fallback: 'blocking',
    }
    return ret
}

I think problem is with " or '. But VSCode automatically converts it to '.

1 Answers

You're getting the type error because when you declare the ret object, TypeScript assumes fallback to be of type string rather than being the literal string 'blocking'. In other words, internally the ret object gets typed as follows, which is incompatible with the expected GetStaticPaths type.

const obj: { 
    paths: { 
        params: { category: string; }; 
    }[];
    fallback: string; // `GetStaticPaths` expects this to be of type `boolean | 'blocking'`
}

To fix the issue, you can either return the object directly, without the intermediate variable.

export const getStaticPaths: GetStaticPaths = async () => {
    //...

    return {
        paths,
        fallback: 'blocking'
    }
}

Or alternatively, cast the fallback value to a const to force the literal string type on it.

export const getStaticPaths: GetStaticPaths = async () => {
    //...

    let ret = {
        paths,
        fallback: 'blocking' as const,
    }
    return ret
}
Related