TypeScript

Next.js incluye TypeScript integrado, instalando automáticamente los paquetes necesarios y configurando los ajustes adecuados cuando creas un nuevo proyecto con create-next-app.

Para añadir TypeScript a un proyecto existente, renombra un archivo a .ts / .tsx. Ejecuta next dev y next build para instalar automáticamente las dependencias necesarias y añadir un archivo tsconfig.json con las opciones de configuración recomendadas.

Nota importante: Si ya tienes un archivo jsconfig.json, copia la opción del compilador paths del antiguo jsconfig.json al nuevo archivo tsconfig.json, y elimina el antiguo jsconfig.json.

Plugin para el IDE

Next.js incluye un plugin personalizado de TypeScript y un verificador de tipos, que VSCode y otros editores de código pueden usar para verificación avanzada de tipos y autocompletado.

Puedes activar el plugin en VS Code mediante:

  1. Abrir la paleta de comandos (Ctrl/⌘ + Shift + P)
  2. Buscar "TypeScript: Seleccionar versión de TypeScript"
  3. Seleccionar "Usar versión del espacio de trabajo"
Paleta de comandos de TypeScript

Ahora, al editar archivos, el plugin personalizado estará activado. Al ejecutar next build, se usará el verificador de tipos personalizado.

El plugin de TypeScript puede ayudar con:

  • Advertir si se pasan valores inválidos para las opciones de configuración de segmentos.
  • Mostrar opciones disponibles y documentación en contexto.
  • Asegurar que la directiva 'use client' se use correctamente.
  • Garantizar que los hooks del cliente (como useState) solo se usen en Componentes del Cliente.

🎥 Ver: Aprende sobre el plugin integrado de TypeScript → YouTube (3 minutos)

Seguridad de tipos de extremo a extremo

El Enrutador de Aplicación de Next.js tiene mayor seguridad de tipos. Esto incluye:

  1. No serialización de datos entre la función de obtención y la página: Puedes usar fetch directamente en componentes, diseños y páginas en el servidor. Estos datos no necesitan ser serializados (convertidos a cadena) para pasarse al lado del cliente. En su lugar, como app usa Componentes del Servidor por defecto, podemos usar valores como Date, Map, Set, y más sin pasos adicionales. Anteriormente, necesitabas tipar manualmente el límite entre el servidor y el cliente con tipos específicos de Next.js.
  2. Flujo de datos simplificado entre componentes: Con la eliminación de _app en favor de diseños raíz, ahora es más fácil visualizar el flujo de datos entre componentes y páginas. Antes, los datos fluyendo entre pages individuales y _app eran difíciles de tipar y podían introducir errores confusos. Con la obtención de datos colocalizada en el Enrutador de Aplicación, esto ya no es un problema.

Obtención de datos en Next.js ahora proporciona la mayor seguridad de tipos de extremo a extremo posible sin ser prescriptivo sobre tu selección de base de datos o proveedor de contenido.

Podemos tipar los datos de respuesta como esperarías con TypeScript normal. Por ejemplo:

async function getData() {
  const res = await fetch('https://api.example.com/...')
  // El valor de retorno *no* está serializado
  // Puedes retornar Date, Map, Set, etc.
  return res.json()
}

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

  return '...'
}

Para una seguridad de tipos completa de extremo a extremo, esto también requiere que tu base de datos o proveedor de contenido soporte TypeScript. Esto podría ser mediante un ORM o constructor de consultas con seguridad de tipos.

Ejemplos

Verificación de tipos en next.config.ts

Puedes usar TypeScript e importar tipos en tu configuración de Next.js usando next.config.ts.

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

const nextConfig: NextConfig = {
  /* opciones de configuración aquí */
}

export default nextConfig

Nota importante: La resolución de módulos en next.config.ts actualmente está limitada a CommonJS. Esto puede causar incompatibilidades con paquetes solo ESM cargados en next.config.ts.

Cuando uses el archivo next.config.js, puedes añadir verificación de tipos en tu IDE usando JSDoc como se muestra a continuación:

next.config.js
// @ts-check

/** @type {import('next').NextConfig} */
const nextConfig = {
  /* opciones de configuración aquí */
}

module.exports = nextConfig

Enlaces con tipos estáticos

Next.js puede tipar estáticamente los enlaces para prevenir errores tipográficos y otros problemas al usar next/link, mejorando la seguridad de tipos al navegar entre páginas.

Para activar esta función, experimental.typedRoutes debe estar habilitado y el proyecto debe usar TypeScript.

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

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

export default nextConfig

Next.js generará una definición de enlace en .next/types que contiene información sobre todas las rutas existentes en tu aplicación, que TypeScript puede usar para proporcionar retroalimentación en tu editor sobre enlaces inválidos.

Actualmente, el soporte experimental incluye cualquier cadena literal, incluyendo segmentos dinámicos. Para cadenas no literales, actualmente necesitas convertir manualmente el href con as Route:

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

// Sin errores de TypeScript si href es una ruta válida
<Link href="/about" />
<Link href="/blog/nextjs" />
<Link href={`/blog/${slug}`} />
<Link href={('/blog' + slug) as Route} />

// Errores de TypeScript si href no es una ruta válida
<Link href="/aboot" />

Para aceptar href en un componente personalizado que envuelva next/link, usa un genérico:

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>Mi Tarjeta</div>
    </Link>
  )
}

¿Cómo funciona?

Al ejecutar next dev o next build, Next.js genera un archivo .d.ts oculto dentro de .next que contiene información sobre todas las rutas existentes en tu aplicación (todas las rutas válidas como el tipo href de Link). Este archivo .d.ts se incluye en tsconfig.json y el compilador de TypeScript verificará ese .d.ts y proporcionará retroalimentación en tu editor sobre enlaces inválidos.

Con Componentes del Servidor Asíncronos

Para usar un Componente del Servidor async con TypeScript, asegúrate de usar TypeScript 5.1.3 o superior y @types/react 18.2.8 o superior.

Si usas una versión anterior de TypeScript, puedes ver un error de tipo 'Promise<Element>' no es un elemento JSX válido. Actualizar a la última versión de TypeScript y @types/react debería resolver este problema.

Verificación de tipos incremental

Desde v10.2.1 Next.js soporta verificación de tipos incremental cuando está habilitada en tu tsconfig.json, esto puede ayudar a acelerar la verificación de tipos en aplicaciones grandes.

Desactivar errores de TypeScript en producción

Next.js falla tu compilación de producción (next build) cuando hay errores de TypeScript en tu proyecto.

Si deseas que Next.js produzca código de producción incluso cuando tu aplicación tenga errores, puedes desactivar el paso de verificación de tipos integrado.

Si lo desactivas, asegúrate de ejecutar verificaciones de tipos como parte de tu proceso de compilación o despliegue, de lo contrario puede ser muy peligroso.

Abre next.config.ts y habilita la opción ignoreBuildErrors en la configuración de typescript:

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

const nextConfig: NextConfig = {
  typescript: {
    // !! ADVERTENCIA !!
    // Permite peligrosamente que las compilaciones de producción se completen con éxito incluso si
    // tu proyecto tiene errores de tipos.
    // !! ADVERTENCIA !!
    ignoreBuildErrors: true,
  },
}

export default nextConfig

Nota importante: Puedes ejecutar tsc --noEmit para verificar errores de TypeScript tú mismo antes de compilar. Esto es útil para pipelines de CI/CD donde quieres verificar errores de TypeScript antes de desplegar.

Declaraciones de tipos personalizadas

Cuando necesites declarar tipos personalizados, podrías sentirte tentado a modificar next-env.d.ts. Sin embargo, este archivo se genera automáticamente, por lo que cualquier cambio que hagas se sobrescribirá. En su lugar, deberías crear un nuevo archivo, por ejemplo new-types.d.ts, y referenciarlo en tu tsconfig.json:

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

Cambios por versión

VersiónCambios
v15.0.0Se añadió soporte para next.config.ts en proyectos con TypeScript.
v13.2.0Los enlaces con tipos estáticos están disponibles en beta.
v12.0.0SWC ahora se usa por defecto para compilar TypeScript y TSX para compilaciones más rápidas.
v10.2.1Se añadió soporte para verificación de tipos incremental cuando está habilitada en tu tsconfig.json.