You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js+TypeScript部署Vercel遇Invalid type错误求助

解决TypeScript ESLint的restrict-template-expressions错误

你遇到的是@typescript-eslint/restrict-template-expressions规则的报错,核心原因是模板字符串中使用了可能为undefined的变量,ESLint要求模板表达式的类型必须是确定的非空值。以下是针对两个文件的具体解决方法:

1. 修复PostList.tsx的错误

报错行:href={/blog/${post.slug}}
问题出在post.slug的类型被定义为string | undefined,ESLint禁止在模板字符串中使用可能未定义的值。

解决方案:

  • 方案一(推荐):强制slug为必填字段
    修改你的Posts类型定义,将slug设为必填项(移除类型后的?):

    interface Post {
      slug: string; // 去掉可选标记?,确保slug始终存在
      frontMatter: FrontMatterType;
      // 其他字段...
    }
    type Posts = { posts: Post[] };
    

    这样TypeScript会强制post.slug始终是字符串,报错会直接消失。

  • 方案二:非空断言或默认值兜底
    若无法修改类型定义,且能保证post.slug实际不会为undefined,可以用非空断言!:

    <Link key={i} href={`/blog/${post.slug!}`}>
    

    或者给默认值避免undefined:

    <Link key={i} href={`/blog/${post.slug ?? 'default-slug'}`}>
    

2. 修复[slug].tsx的错误

报错行:fs.readFileSync(posts/${context.params?.slug}.md)
问题是context.params?.slug可能为undefined,因为TypeScript默认将params标记为可选类型。

解决方案:

  • 方案一:结合getStaticPaths的非空断言
    由于你使用静态生成(getStaticProps),通常会配合getStaticPaths返回所有合法slug,此时context.params.slug必然存在,可直接用非空断言!:

    const mdfile = fs.readFileSync(`posts/${context.params!.slug}.md`);
    
  • 方案二:显式约束params类型
    给GetStaticProps指定泛型,明确params的结构,让TypeScript知道slug是必填字符串:

    import { GetStaticProps } from 'next';
    
    interface FrontMatterType {
      // 你的 frontMatter 字段定义
    }
    
    export const getStaticProps: GetStaticProps<
      { frontMatter: FrontMatterType; content: string },
      { slug: string } // 指定params的类型
    > = (context) => {
      const mdfile = fs.readFileSync(`posts/${context.params.slug}.md`);
      const { data: frontMatter, content } = matter(mdfile);
    
      return {
        props: {
          frontMatter,
          content,
        }
      }
    }
    
  • 方案三:运行时检查兜底
    加一层判断确保slug存在,避免运行时出现文件找不到的错误:

    export const getStaticProps: GetStaticProps = (context) => {
      const slug = context.params?.slug;
      if (!slug) {
        throw new Error('Slug parameter is missing');
      }
      const mdfile = fs.readFileSync(`posts/${slug}.md`);
      const { data: frontMatter, content } = matter(mdfile);
    
      return {
        props: {
          frontMatter,
          content,
        }
      }
    }
    

内容的提问来源于stack exchange,提问作者takeOne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 05:50:34