首页 / Next.js 16 入门教程 / TypeScript 集成

Next.js 16 入门教程

TypeScript 集成

本教程共 42 篇 · 第 24 篇 · 更新于 2026-07-30 · 约 7 分钟阅读

Next.jsNext.js 16 入门教程TypeScript类型安全类型生成

24. TypeScript 集成

本节目标:搞懂 Next.js 怎么集成 TypeScript,学会类型生成、类型安全路由和环境变量类型提示这些进阶用法。

为什么 Next.js 推荐 TypeScript

Next.js 提供开箱即用的 TypeScript 支持。当你使用 create-next-app 创建项目时,会自动安装必要的依赖并配置好 tsconfig.json。即使是已有项目,只需将文件重命名为 .ts / .tsx,然后运行 next dev,Next.js 就会自动完成 TypeScript 的配置。

# 将 app/page.js 重命名为 app/page.tsx
mv app/page.js app/page.tsx

# 启动开发服务器,Next.js 会自动安装依赖
npm run dev
Tip

如果你已有 jsconfig.json,建议将其中的 paths 配置复制到新的 tsconfig.json 中,然后删除旧的 jsconfig.json

端到端类型安全

App Router 还带来一个重要改进:端到端类型安全。Pages Router 时代,服务端的数据要先手动序列化才能传给客户端,你还得用特殊类型标注服务端和客户端的边界。

而在 App Router 中,由于默认使用 Server Components,数据不需要序列化,你可以直接使用 DateMapSet 等类型:

// app/page.tsx
async function getData() {
  const res = await fetch('https://api.example.com/posts')
  // 返回值不会被序列化
  // 可以直接返回 Date、Map、Set 等类型
  return res.json()
}

export default async function Page() {
  const data = await getData()

  return (
    <div>
      <p>更新时间: {new Date(data.updatedAt).toLocaleDateString()}</p>
    </div>
  )
}

要实现完整的端到端类型安全,还需要你的数据库或内容提供商支持 TypeScript。通常可以通过 ORM(如 Prisma、Drizzle)或类型安全的查询构建器来实现。

路由感知类型助手

Next.js 会在构建时(next devnext buildnext typegen)自动生成全局类型助手,无需手动导入:

类型助手用途
PageProps页面组件的 props 类型
LayoutProps布局组件的 props 类型
RouteContext路由上下文类型

这些类型在编辑器的智能提示中自动生效,让你无需关心导入路径。

next-env.d.ts

Next.js 会在项目根目录生成一个 next-env.d.ts 文件。这个文件引用了 Next.js 的类型定义,让 TypeScript 能够识别非代码导入(如图片、样式表)以及 Next.js 特有的类型。

Important

next-env.d.ts 由 Next.js 自动管理,不应该手动编辑,也不应该提交到 Git。建议将其加入 .gitignore

IDE 插件

Next.js 内置了一个自定义 TypeScript 插件,可以提供更强大的类型检查和自动补全功能。在 VS Code 中启用方法:

  1. 打开命令面板(Ctrl/⌘ + Shift + P
  2. 搜索 “TypeScript: Select TypeScript Version”
  3. 选择 “Use Workspace Version”

启用后,插件会提供以下功能:

  • 警告无效的路段配置选项值
  • 显示可用选项和上下文文档
  • 确保 'use client' 指令使用正确
  • 确保客户端 hooks(如 useState)只在客户端组件中使用

静态类型链接

Next.js 可以让 next/linkhref 属性进行静态类型检查,防止拼写错误导致的路由问题。

首先在 next.config.ts 中启用 typedRoutes

// next.config.ts
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  typedRoutes: true,
}

export default nextConfig

启用后,Next.js 会在 .next/types 目录生成一个类型定义文件,包含所有路由信息。TypeScript 会自动验证链接是否指向有效路由:

'use client'

import type { Route } from 'next'
import Link from 'next/link'
import { useRouter } from 'next/navigation'

export default function Example() {
  const router = useRouter()
  const slug = 'nextjs'

  return (
    <>
      {/* 字面量字符串,自动验证 */}
      <Link href="/about">关于</Link>
      <Link href={`/blog/${slug}`}>博客</Link>

      {/* 非字面量字符串,需要手动断言 */}
      <Link href={('/blog/' + slug) as Route}>博客</Link>

      {/* TypeScript 报错:不存在此路由 */}
      <Link href="/aboot">错误链接</Link>
    </>
  )
}
Note

如果你的项目不是用 create-next-app 创建的,需要在 tsconfig.jsoninclude 数组中添加 .next/types/**/*.ts

环境变量类型提示

在开发过程中,Next.js 可以自动为环境变量生成类型定义。启用 experimental.typedEnv 后,编辑器会提供环境变量名的智能提示:

// next.config.ts
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    typedEnv: true,
  },
}

export default nextConfig
Tip

类型是基于开发运行时加载的环境变量生成的,默认不包含 .env.production* 文件中的变量。如需包含生产环境变量,使用 NODE_ENV=production next dev 运行。

配置文件的类型检查

使用 next.config.ts 可以获得完整的类型支持:

// next.config.ts
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  /* 配置选项 */
}

export default nextConfig

如果使用 next.config.js,可以通过 JSDoc 添加类型检查:

// next.config.js
// @ts-check

/** @type {import('next').NextConfig} */
const nextConfig = {
  /* 配置选项 */
}

module.exports = nextConfig

自定义类型声明

当需要声明自定义类型时,不要修改 next-env.d.ts(因为它会被自动覆盖)。应该创建一个新文件,例如 types.d.ts

// tsconfig.json
{
  "compilerOptions": {
    "skipLibCheck": true
  },
  "include": [
    "types.d.ts",
    "next-env.d.ts",
    ".next/types/**/*.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": ["node_modules"]
}

types.d.ts 中声明全局类型:

// types.d.ts
declare global {
  interface User {
    id: string
    name: string
    email: string
    role: 'admin' | 'user'
  }
}

export {}

异步 Server Component 的类型要求

要在 TypeScript 中使用异步 Server Component,需要确保版本满足以下要求:

  • TypeScript 5.1.3 或更高版本
  • @types/react 18.2.8 或更高版本

如果使用较旧版本,可能会遇到 'Promise<Element>' is not a valid JSX element 类型错误。更新依赖即可解决:

npm install -D typescript@latest @types/react@latest

生产构建的类型检查

默认情况下,当项目存在 TypeScript 错误时,next build 会失败。这是为了确保生产代码的类型安全。

如果你确实需要在有类型错误的情况下构建(不推荐),可以禁用内置类型检查:

// next.config.ts
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  typescript: {
    // !! 警告 !!
    // 允许项目存在类型错误时仍完成生产构建
    // !! 警告 !!
    ignoreBuildErrors: true,
  },
}

export default nextConfig
Warning

禁用类型检查后,请确保在 CI/CD 流程中单独运行 tsc --noEmit 进行类型检查。

自定义 tsconfig 路径

在某些场景下,你可能希望为构建使用不同的 TypeScript 配置。例如,在 monorepo 中,构建可能需要验证共享依赖,而这些依赖可能不完全符合项目的严格标准:

// next.config.ts
import type { NextConfig } from 'next'

const isProd = process.env.NODE_ENV === 'production'

const nextConfig: NextConfig = {
  typescript: {
    tsconfigPath: isProd ? 'tsconfig.build.json' : 'tsconfig.json',
  },
}

export default nextConfig

对应的 tsconfig.build.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "useUnknownInCatchVariables": false
  }
}

这样,编辑器保持严格模式,而生产构建使用宽松配置。

小结

这一章我们学了 Next.js 的 TypeScript 集成:

  1. Next.js 自动管理 next-env.d.ts,别手动改
  2. 启用 typedRoutes 能拿到路由级别的类型安全
  3. next.config.ts 让配置文件也有完整类型支持
  4. 异步 Server Component 需要 TypeScript 5.1.3+ 和 @types/react 18.2.8+