TypeScript

Next.js имеет встроенную поддержку TypeScript, автоматически устанавливая необходимые пакеты и настраивая параметры при создании нового проекта с помощью create-next-app.

Чтобы добавить TypeScript в существующий проект, переименуйте файл в .ts / .tsx. Запустите next dev и next build, чтобы автоматически установить необходимые зависимости и добавить файл tsconfig.json с рекомендуемыми настройками.

Полезно знать: Если у вас уже есть файл jsconfig.json, скопируйте параметр компилятора paths из старого jsconfig.json в новый tsconfig.json и удалите старый jsconfig.json.

Плагин для IDE

Next.js включает пользовательский плагин TypeScript и проверку типов, которые могут использоваться VSCode и другими редакторами кода для расширенной проверки типов и автодополнения.

Вы можете включить плагин в VS Code следующим образом:

  1. Откройте палитру команд (Ctrl/⌘ + Shift + P)
  2. Найдите "TypeScript: Select TypeScript Version"
  3. Выберите "Use Workspace Version"
Палитра команд TypeScript

Теперь при редактировании файлов будет активирован пользовательский плагин. При запуске next build будет использоваться пользовательская проверка типов.

Плагин TypeScript может помочь с:

  • Предупреждением о передаче недопустимых значений для опций конфигурации сегментов.
  • Отображением доступных опций и контекстной документации.
  • Проверкой правильности использования директивы 'use client'.
  • Обеспечением того, что клиентские хуки (например, useState) используются только в клиентских компонентах.

🎥 Видео: Узнайте о встроенном плагине TypeScript → YouTube (3 минуты)

Сквозная типобезопасность

App Router в Next.js обеспечивает расширенную типобезопасность. Это включает:

  1. Отсутствие сериализации данных между функциями получения данных и страницами: Вы можете использовать fetch напрямую в компонентах, лейаутах и страницах на сервере. Эти данные не требуют сериализации (преобразования в строку) для передачи на клиентскую сторону. Поскольку app по умолчанию использует серверные компоненты, мы можем использовать значения типа Date, Map, Set и другие без дополнительных шагов. Ранее требовалось вручную типизировать границу между сервером и клиентом с использованием специфичных для Next.js типов.
  2. Упрощенный поток данных между компонентами: С заменой _app на корневые лейауты стало проще визуализировать поток данных между компонентами и страницами. Ранее типизация данных, передаваемых между отдельными pages и _app, была сложной и могла приводить к ошибкам. С совместным размещением получения данных в App Router эта проблема устранена.

Получение данных в Next.js теперь обеспечивает максимально возможную сквозную типобезопасность без ограничений в выборе базы данных или провайдера контента.

Мы можем типизировать данные ответа, как и ожидается в обычном TypeScript. Например:

async function getData() {
  const res = await fetch('https://api.example.com/...')
  // Возвращаемое значение *не* сериализуется
  // Можно возвращать Date, Map, Set и т.д.
  return res.json()
}

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

  return '...'
}

Для полной сквозной типобезопасности также требуется, чтобы ваша база данных или провайдер контента поддерживали TypeScript. Это может быть реализовано через использование ORM или типобезопасного построителя запросов.

Примеры

Проверка типов в next.config.ts

Вы можете использовать TypeScript и импортировать типы в конфигурации Next.js через next.config.ts.

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

const nextConfig: NextConfig = {
  /* параметры конфигурации здесь */
}

export default nextConfig

Полезно знать: Разрешение модулей в next.config.ts в настоящее время ограничено CommonJS. Это может вызвать несовместимости с пакетами, работающими только с ESM, при загрузке в next.config.ts.

При использовании файла next.config.js вы можете добавить проверку типов в вашей IDE через JSDoc, как показано ниже:

next.config.js
// @ts-check

/** @type {import('next').NextConfig} */
const nextConfig = {
  /* параметры конфигурации здесь */
}

module.exports = nextConfig

Статически типизированные ссылки

Next.js может статически типизировать ссылки, чтобы предотвратить опечатки и другие ошибки при использовании next/link, улучшая типобезопасность при навигации между страницами.

Для включения этой функции необходимо активировать experimental.typedRoutes и использовать TypeScript в проекте.

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

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

export default nextConfig

Next.js сгенерирует определение ссылок в .next/types, содержащее информацию обо всех существующих маршрутах вашего приложения, которую TypeScript может использовать для предоставления обратной связи в вашем редакторе о недопустимых ссылках.

В настоящее время экспериментальная поддержка включает любые строковые литералы, включая динамические сегменты. Для нелитеральных строк требуется вручную приводить href к типу as Route:

import type { Route } from 'next';
import Link from 'next/link'

// Ошибок TypeScript не будет, если href является допустимым маршрутом
<Link href="/about" />
<Link href="/blog/nextjs" />
<Link href={`/blog/${slug}`} />
<Link href={('/blog' + slug) as Route} />

// Ошибки TypeScript, если href не является допустимым маршрутом
<Link href="/aboot" />

Для принятия href в пользовательском компоненте, оборачивающем next/link, используйте generic:

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

function Card<T extends string>({ href }: { href: Route<T> | URL }) {
  return (
    <Link href={href}>
      <div>My Card</div>
    </Link>
  )
}

Как это работает?

При запуске next dev или next build Next.js генерирует скрытый .d.ts файл внутри .next, содержащий информацию обо всех существующих маршрутах вашего приложения (все допустимые маршруты как тип href для Link). Этот .d.ts файл включается в tsconfig.json, и компилятор TypeScript будет проверять его и предоставлять обратную связь в вашем редакторе о недопустимых ссылках.

С асинхронными серверными компонентами

Для использования async серверных компонентов с TypeScript убедитесь, что вы используете TypeScript 5.1.3 или выше и @types/react 18.2.8 или выше.

Если вы используете более старую версию TypeScript, вы можете увидеть ошибку типа 'Promise<Element>' is not a valid JSX element. Обновление до последней версии TypeScript и @types/react должно решить эту проблему.

Инкрементальная проверка типов

Начиная с версии v10.2.1 Next.js поддерживает инкрементальную проверку типов при включении в вашем tsconfig.json, что может ускорить проверку типов в больших приложениях.

Отключение ошибок TypeScript в production

Next.js завершает production сборку (next build) с ошибкой, если в проекте присутствуют ошибки TypeScript.

Если вы хотите, чтобы Next.js опасно продолжал сборку даже при наличии ошибок в приложении, вы можете отключить встроенную проверку типов.

Если проверка отключена, убедитесь, что вы выполняете проверку типов как часть процесса сборки или развертывания, иначе это может быть очень опасно.

Откройте next.config.ts и включите опцию ignoreBuildErrors в конфигурации typescript:

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

const nextConfig: NextConfig = {
  typescript: {
    // !! ВНИМАНИЕ !!
    // Опасное разрешение на успешное завершение production сборки
    // даже при наличии ошибок типов в вашем проекте.
    // !! ВНИМАНИЕ !!
    ignoreBuildErrors: true,
  },
}

export default nextConfig

Полезно знать: Вы можете запустить tsc --noEmit для самостоятельной проверки ошибок TypeScript перед сборкой. Это полезно для CI/CD пайплайнов, где вы хотите проверить ошибки TypeScript перед развертыванием.

Пользовательские объявления типов

Когда вам нужно объявить пользовательские типы, может возникнуть соблазн изменить next-env.d.ts. Однако этот файл генерируется автоматически, и любые изменения будут перезаписаны. Вместо этого создайте новый файл, например new-types.d.ts, и укажите его в вашем tsconfig.json:

tsconfig.json
{
  "compilerOptions": {
    "skipLibCheck": true
    //...сокращено...
  },
  "include": [
    "new-types.d.ts",
    "next-env.d.ts",
    ".next/types/**/*.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": ["node_modules"]
}

Изменения в версиях

ВерсияИзменения
v15.0.0Добавлена поддержка next.config.ts для TypeScript-проектов.
v13.2.0Статически типизированные ссылки доступны в бета-версии.
v12.0.0SWC теперь используется по умолчанию для компиляции TypeScript и TSX для ускорения сборки.
v10.2.1Добавлена поддержка инкрементальной проверки типов при включении в tsconfig.json.