Next.js+TypeScript部署Vercel遇Invalid type错误求助
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

