由于参数未定义,下一个 js 在使用 getStaticProps 构建时失败

nie*_*oof 5 typescript next.js

开始出现奇怪的错误,导致构建失败,

我们的页面目录中有一个 post/[id].tsx 文件,该文件使用getStaticPropsgetStaticPaths

- 道具

export const getStaticProps: GetStaticProps = async ({ params }) => {
  const res: Response = await fetch(`${baseUrl}/api/products/${params.id}`);

  const data: Product[] = await res.json();

  return {
    props: {
      data,
    },
  };
};
Run Code Online (Sandbox Code Playgroud)

-- 路径

export const getStaticPaths: GetStaticPaths = async () => {
  const res: Response = await fetch(`${baseUrl}/api/products`);
  const { data } = await res.json();

  const paths = data.map((product: Product) => ({
    params: { id: product.id.toString() },
  }));
  return { paths, fallback: "blocking" };
};
Run Code Online (Sandbox Code Playgroud)

在本地运行npm run dev并且一切按预期工作,但是运行npm run build并出现错误

Type error: Object is possibly 'undefined'.
Run Code Online (Sandbox Code Playgroud)

getStaticProps 函数内部

> 12 |   const res: Response = await fetch(`${baseUrl}/api/products/${params.id}`);
                                                                      ^
Run Code Online (Sandbox Code Playgroud)

现在奇怪的是,当前在 vercel 上部署的构建使用完全相同的代码来构建此页面,并且没有任何变化。但现在构建突然失败?

Chu*_*uji 7

这是上面 @Pranta 的答案的一个分支,做了一些修改。虽然 Pranta 的解决方案在很大程度上解决了问题,但 Typescript 会在id变量声明中发出相同的警告,尽管这可能不会导致构建失败。在继续之前,请务必注意出现警告,因为 Next 对象的类型定义paramsParsedUrlQuery | undefined

解决该问题并完全消除警告的一种方法是将对象的类型断言为paramsParsedUrlQuery如下所示:

// The import should happen automatically in VSCode, but if it doesn't
import { ParsedUrlQuery } from 'querystring';

const id = (params as ParsedUrlQuery).id;
const res: Response = await fetch(`${baseUrl}/api/products/${id}`);
Run Code Online (Sandbox Code Playgroud)

虽然这有效,但它仍然不是最好的解决方案。params我推荐的一个更好的解决方案是在函数中进行 API 调用之前检查对象是否实际定义getStaticProps。这样,您还可以避免随后遇到问题。因此,我们有:

if (params) {
  const id = params.id;
  const res: Response = await fetch(`${baseUrl}/api/products/${id}`);
}
Run Code Online (Sandbox Code Playgroud)

我们可以重构代码并添加额外的检查,以确保id实际从函数中检索到路径参数的值getStaticPaths

if (params && params.id) {
  const res: Response = await fetch(`${baseUrl}/api/products/${params.id}`);
}
Run Code Online (Sandbox Code Playgroud)

最后,因为getStaticProps函数期望返回一个值,所以我们必须指定一个默认返回值来模仿函数期望的返回值的结构,如下所示。

export const getStaticProps: GetStaticProps = async ({ params }) => {
  if (params && params.id) {
    const res: Response = await fetch(`${baseUrl}/api/products/${params.id}`);
    const data: Product[] = await res.json();
    return {
      props: { data },
    };
  }

  // Here, I'm returning an error property in the props object, but you can choose to return something else that suits your need.
  return {
    props: { error: true },
  };
};
Run Code Online (Sandbox Code Playgroud)


Pra*_*nta 2

这里的问题是 next.js 在这里进行类型检查,而 typescript 认为你的参数可能在这里未定义。只要告诉打字稿它不是。

  const id = params.id!
  const res: Response = await fetch(`${baseUrl}/api/products/${id}`);
Run Code Online (Sandbox Code Playgroud)

这应该有效。