CodeForge

TypeScript de Cero a Experto / Configuración pro

Chequeos extra: la segunda capa de rigor

Teoría20 min20 XP

strict cubre lo esencial, pero TypeScript guarda una segunda capa de comprobaciones que NO vienen en strict y que valen oro: la que atrapa accesos a arrays inseguros, variables muertas y returns olvidados. Activarlas es lo que separa un proyecto bueno de uno impecable —el nivel de configuración de los equipos que se toman la calidad en serio.

Las alarmas opcionales que sí vale la pena poner

noUncheckedIndexedAccess: el hueco de los arrays

El chequeo más importante que NO está en strict. Sin él, array[i] se tipa como T —mintiendo, porque el índice podría no existir:

unchecked-index.ts
const gastos: number[] = [100, 200, 300];

// SIN noUncheckedIndexedAccess (default): TS miente diciendo que es number
const x = gastos[10];       // tipo: number (¡pero en runtime es undefined!)
x.toFixed(2);               // ✅ para TS... 💥 undefined.toFixed en runtime

// CON noUncheckedIndexedAccess: TS es honesto, el acceso es T | undefined
const y = gastos[10];       // tipo: number | undefined
y.toFixed(2);               // ❌ 'y' is possibly 'undefined' — TS te frena
if (y !== undefined) y.toFixed(2);   // ✓ te obliga a chequear

strictNullChecks cubre los null de variables, pero deja este agujero: acceder a un índice que no existe da undefined en runtime, y sin noUncheckedIndexedAccess, TS lo tipa como si siempre existiera. Activarlo cierra el hueco —a cambio de que manejes el undefined en accesos por índice. Molesta un poco, previene mucho; muchos equipos serios lo consideran casi obligatorio.

Código muerto: noUnusedLocals y noUnusedParameters

Estos cazan variables y parámetros que declaras pero nunca usas —basura que se acumula y confunde:

no-unused.ts
function calcular(a: number, b: number, c: number): number {
const temporal = a * 2;    // ❌ noUnusedLocals: 'temporal' is declared but never used.
return a + b;              // ❌ noUnusedParameters: 'c' is declared but never used.
}

// te obligan a limpiar: borrar lo que no usas, o marcar params intencionalmente
// sin usar con un guion bajo (convención que estos flags respetan):
function manejar(_evento: Event, datos: string): void {
console.log(datos);   // _evento no se usa, y el _ lo declara intencional
}

noUnusedLocals y noUnusedParameters mantienen tu código limpio: nada de variables olvidadas ni parámetros fantasma. El truco del guion bajo (_evento) le dice "sé que no lo uso, es a propósito" —útil cuando la firma exige un parámetro que no necesitas.

Blindar el flujo: switch y returns

Dos chequeos que atrapan errores de lógica clásicos:

flujo.ts
// noImplicitReturns: TODAS las rutas deben devolver (o ninguna):
function clasificar(n: number): string {
if (n > 0) return "positivo";
if (n < 0) return "negativo";
// ❌ noImplicitReturns: Not all code paths return a value. (falta el caso n === 0)
}

// noFallthroughCasesInSwitch: un case sin 'break'/'return' que "cae" al siguiente es error:
function color(estado: string): string {
switch (estado) {
  case "activo":
    console.log("activo");
    // ❌ noFallthroughCasesInSwitch: falta break/return, cae en "inactivo"
  case "inactivo":
    return "gris";
  default:
    return "negro";
}
}

Con strict activo, escribes const primero = miArray[0] y usas primero.nombre sin chequear, y en producción a veces sale undefined. ¿Qué flag lo habría cazado?

Mini-reto

Sube el rigor: 1) en un tsconfig, agrega noUncheckedIndexedAccess: true y observa cómo un array[0] ahora es T | undefined; 2) deja una variable local sin usar con noUnusedLocals activo y mira el error; 3) escribe una función con un if que no cubre todos los casos con noImplicitReturns y observa la queja. Siente cómo cada flag te empuja a un código más honesto.

Qué sigue

Tu compilador ya es riguroso. Ahora hagámoslo cómodo: los paths de TypeScript te dejan escribir @/componentes/Boton en vez de ../../../componentes/Boton —adiós a los imports con laberintos de puntos. La próxima lección configura la resolución de módulos para que tu código se lea limpio.