Modo Estricto de TypeScript y Verificaciones del Compilador
Habilita las opciones estrictas del compilador de TypeScript para detectar más errores en tiempo de compilación y complementar ESLint con seguridad de tipos.
Busca en todas las páginas de la documentación
Habilita las opciones estrictas del compilador de TypeScript para detectar más errores en tiempo de compilación y complementar ESLint con seguridad de tipos.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Tarjeta de referencia rápida - lista para copiar y pegar.
# Verifica tipos sin emitir archivos
npx tsc --noEmit
# Verifica tipos en modo watch durante desarrollo
npx tsc --noEmit --watch
# Agregue a package.json
# "type-check": "tsc --noEmit"Cuándo usarlo: Todo proyecto TypeScript debe habilitar strict mode. La pregunta no es si, sino qué tan rápido puedes activar cada opción.
// tsconfig.json
{
"compilerOptions": {
// --- Strict mode (flag sombrilla) ---
"strict": true,
// "strict" habilita todas estas:
// "strictNullChecks": true,
// "strictFunctionTypes": true,
// "strictBindCallApply": true,
// "strictPropertyInitialization": true,
// "noImplicitAny": true,
// "noImplicitThis": true,
// "alwaysStrict": true,
// "useUnknownInCatchVariables": true,
// --- Verificaciones estrictas adicionales (no en "strict") ---
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"exactOptionalPropertyTypes": true,
// --- Configuración de módulos e imports ---
"verbatimModuleSyntax": true,
"moduleResolution": "bundler",
"module": "esnext",
"target": "es2017",
// --- Alias de rutas ---
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
// --- Salida ---
"noEmit": true,
"jsx": "preserve",
"incremental": true,
// --- Interoperabilidad ---
"esModuleInterop": true,
"allowJs": true,
"resolveJsonModule": true,
"isolatedModules": true,
"skipLibCheck": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}Lo que esto demuestra:
strict completo habilitado como línea basestrict para máxima seguridadverbatimModuleSyntax para imports de solo tipo explícitosnoUncheckedIndexedAccess para forzar verificaciones nulas en acceso a arrays y objetosnoEmit, jsx: "preserve", moduleResolution: "bundler")"strict": true es una flag sombrilla que habilita ocho verificaciones estrictas individualesnoUncheckedIndexedAccess no están incluidas en strict y deben habilitarse por separadotsc --noEmit ejecuta el verificador de tipos sin producir archivos de salida (Next.js maneja la compilación vía SWC)Lo que cada opción estricta detecta:
| Opción | Qué Detecta |
|---|---|
strictNullChecks | Acceso a valores potencialmente null o undefined sin verificación |
noImplicitAny | Variables o parámetros sin tipo que asumen el tipo any |
strictFunctionTypes | Asignaciones de tipo de parámetro de función inseguras |
noUncheckedIndexedAccess | Acceso a array[i] u obj[key] sin verificación nula |
noImplicitReturns | Funciones que no retornan un valor en todas las rutas de código |
noFallthroughCasesInSwitch | Falta de break o return en casos switch |
noImplicitOverride | Anulación de métodos de clase base sin palabra clave override |
exactOptionalPropertyTypes | Asignación explícita de undefined a propiedades opcionales |
verbatimModuleSyntax | Fuerza import type para imports de solo tipo |
Habilitación del modo estricto incrementalmente:
// Paso 1: Comienza con strict false pero habilita opciones una por una
{
"compilerOptions": {
"strict": false,
"strictNullChecks": true, // Habilita primero - máximo impacto
"noImplicitAny": true // Habilita segundo
// Agrega más conforme corriges errores
}
}# Cuenta errores restantes para rastrear progreso
npx tsc --noEmit 2>&1 | grep "error TS" | wc -lReglas typescript-eslint que complementan tsconfig:
// Estas reglas ESLint detectan patrones que tsc no marca:
{
rules: {
"@typescript-eslint/no-floating-promises": "error", // Promesas no manejadas
"@typescript-eslint/no-misused-promises": "error", // Promesas en contextos incorrectos
"@typescript-eslint/await-thenable": "error", // await en no-Promise
"@typescript-eslint/no-unnecessary-condition": "warn", // Condiciones siempre-verdaderas
"@typescript-eslint/prefer-nullish-coalescing": "warn", // || vs ??
"@typescript-eslint/strict-boolean-expressions": "warn", // Verificaciones verídicas en no-booleans
},
}Nota: Estas reglas requieren que parserOptions.project esté configurado para linting consciente de tipos.
// verbatimModuleSyntax fuerza imports de tipo explícitos:
import type { User } from "@/types"; // Solo tipo - borrado en runtime
import { fetchUser } from "@/lib/api"; // Valor - mantenido en runtime
// noUncheckedIndexedAccess en acción:
const items = ["a", "b", "c"];
const first = items[0]; // Tipo: string | undefined (no string)
if (first) {
console.log(first.toUpperCase()); // Seguro - estrechado a string
}
// Sin noUncheckedIndexedAccess:
const risky = items[0]; // Tipo: string (miente - podría ser undefined)
risky.toUpperCase(); // Crash en runtime si el array está vacíoCosas que te atraparan. Cada trampa incluye qué sale mal, por qué sucede, y la solución.
strictNullChecks crea muchos errores - Habilitar esto en un proyecto grande existente puede producir cientos o miles de errores. Solución: Habilita incrementalmente. Usa // @ts-expect-error temporalmente para código seguro conocido y corrige errores archivo por archivo.
noUncheckedIndexedAccess es ruidoso - Cada array[i] y obj[key] se convierte en T | undefined, requiriendo verificaciones nulas incluso cuando sabes que el valor existe. Solución: Usa aserción no-nula (items[0]!) esporádicamente donde has verificado que el valor existe, o usa .at(0) con una verificación nula.
exactOptionalPropertyTypes rompe patrones comunes - Ya no puedes escribir { name?: string } y asignar undefined explícitamente. Solución: Solo habilita esto si tu código distingue entre propiedades "faltantes" y "explícitamente undefined". La mayoría de proyectos saltan esta opción.
Las reglas ESLint conscientes de tipos son lentas - Reglas como no-floating-promises requieren información de tipo completa, haciendo ESLint 2 a 5 veces más lento. Solución: Solo habilita reglas conscientes de tipos si el tradeoff vale la pena. Considera ejecutarlas solo en CI, no en el editor.
verbatimModuleSyntax y CommonJS - Esta opción no funciona bien con módulos CommonJS. Solución: Solo habilítala en proyectos usando módulos ES (que incluye todos los proyectos Next.js App Router).
Otras formas de resolver el mismo problema - y cuándo cada una es la mejor opción.
| Alternativa | Úsalo Cuando | No lo Uses Cuando |
|---|---|---|
strict: false con flags individuales | Migrando un código base grande de JavaScript a TypeScript | Iniciando un proyecto nuevo (solo usa strict: true) |
| Solo reglas ESLint conscientes de tipos | Quieres verificaciones de patrones sin cambiar tsconfig | Necesitas garantías en tiempo de compilación |
// @ts-strict por archivo | Quieres modo estricto en archivos nuevos pero no en código heredado | Puedes habilitarlo a nivel de proyecto |
Habilita ocho flags individuales:
strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitializationnoImplicitAny, noImplicitThis, alwaysStrict, useUnknownInCatchVariablesstrictNullChecks -- tiene el mayor impacto y detecta los errores más reales.noImplicitAny segundo.const items = ["a", "b", "c"];
const first = items[0]; // Tipo: string | undefined (no string)
if (first) {
console.log(first.toUpperCase()); // Seguro después de estrechar
}Fuerza verificaciones nulas en cada acceso de índice de array y objeto.
array[i] y obj[key] se convierte en T | undefined.items[0]! esporádicamente para valores verificados, o usa .at(0) con una verificación.import type explícito para imports de solo tipo.npx tsc --noEmit 2>&1 | grep "error TS" | wc -lRastrea este número en el tiempo para medir progreso de migración.
tsconfig detectan problemas a nivel de tipo (seguridad nula, any implícito, desajustes de tipo).@typescript-eslint detectan patrones de código (promesas flotantes, condiciones innecesarias, uso any explícito).undefined explícitamente a propiedades opcionales.no-floating-promises y no-misused-promises requieren información de tipo completa.tsc --noEmit solo verifica tipos sin producir archivos de salida.// @ts-expect-error -- conocido seguro, se arreglará en JIRA-123
const value = riskyFunction();@ts-expect-error temporalmente para código conocido seguro durante migración incremental.@ts-ignore, produce error si el problema suprimido se arregla (manteniendo supresiones honestas).{
rules: {
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/prefer-nullish-coalescing": "warn",
}
}Estas detectan patrones que tsc no marca.
tsc --noEmit en CIRevisado por Chris St. John·Última actualización: 19 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥