TypeScript

Next.js предоставляет TypeScript-ориентированный опыт разработки для создания React-приложений.

Фреймворк включает встроенную поддержку TypeScript для автоматической установки необходимых пакетов и настройки параметров конфигурации.

А также Плагин TypeScript для вашего редактора.

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

Новые проекты

create-next-app теперь по умолчанию использует TypeScript.

Терминал
npx create-next-app@latest

Существующие проекты

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

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

Плагин TypeScript

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

Настоятельно рекомендуется использовать как минимум TypeScript v4.5.2 для получения таких возможностей, как модификаторы типов в именах импортов и улучшения производительности.

Статическая типизация ссылок

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

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

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    typedRoutes: true,
  },
}

module.exports = 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 будет проверять его и предоставлять обратную связь в редакторе о невалидных ссылках.

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

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

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

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

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

app/page.tsx
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 или типобезопасного построителя запросов.

Ошибка TypeScript в Async Server Component

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

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

Передача данных между серверными и клиентскими компонентами

При передаче данных между Серверным и Клиентским Компонентом через пропсы данные всё ещё сериализуются (преобразуются в строку) для использования в браузере. Однако для этого не требуется специальный тип. Типизация происходит так же, как при передаче любых других пропсов между компонентами.

Кроме того, меньше кода требует сериализации, поскольку неотрисованные данные не передаются между сервером и клиентом (они остаются на сервере). Это стало возможным благодаря поддержке Серверных Компонентов.

Алиасы путей и baseUrl

Next.js автоматически поддерживает опции "paths" и "baseUrl" в tsconfig.json.

Подробнее об этой функции можно узнать в документации Алиасы модулей и абсолютные импорты.

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

Файл next.config.js должен быть JavaScript-файлом, так как он не обрабатывается Babel или TypeScript, но вы можете добавить проверку типов в вашей IDE с помощью JSDoc:

// @ts-check

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

module.exports = nextConfig

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

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

Игнорирование ошибок TypeScript

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

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

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

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

next.config.js
module.exports = {
  typescript: {
    // !! ВНИМАНИЕ !!
    // Опасное разрешение на успешное завершение продакшен-сборки
    // даже при наличии ошибок типов в проекте.
    // !! ВНИМАНИЕ !!
    ignoreBuildErrors: true,
  },
}

Кастомные объявления типов

Когда вам нужно объявить кастомные типы, может возникнуть соблазн изменить 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"]
}

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

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