Entiendes lo que el modo estricto activa realmente y sabes gestionar los errores típicos que revela en un proyecto existente.
Abrir esta lección en Kodokon"strict": true no es una opción sino un agregado que activa toda una familia de comprobaciones: strictNullChecks, noImplicitAny, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitThis, useUnknownInCatchVariables y alwaysStrict. Cada nueva versión de TypeScript puede añadir más: activar strict te suscribe a las comprobaciones futuras. Cada flag se puede seguir desactivando individualmente, lo que permite una migración gradual en una base de código existente.
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"noFallthroughCasesInSwitch": true,
"exactOptionalPropertyTypes": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true
}
}Los dos flags de mayor impacto son strictNullChecks y noImplicitAny. El primero elimina null y undefined de todos los tipos: cada valor potencialmente ausente debe declararse T | undefined y gestionarse antes de usarlo. El segundo se niega a dejar que un parámetro sin anotar recaiga en any. Juntos, eliminan las dos grandes familias de bugs de JavaScript: "cannot read property of undefined" y la propagación de valores sin verificar. useUnknownInCatchVariables completa el cuadro: la variable de un catch es unknown, porque JavaScript te deja lanzar cualquier cosa.
function findPort(
env: Record<string, string | undefined>
): number {
const raw = env["PORT"];
if (raw === undefined) {
return 3000;
}
return Number.parseInt(raw, 10);
}
declare function riskyOperation(): void;
try {
riskyOperation();
} catch (err) {
const message =
err instanceof Error ? err.message : String(err);
console.error(message);
}Errores comunes de migración, y sus remedios reales. "Object is possibly undefined": prefiere la reducción (if), el encadenamiento opcional ?. o un valor por defecto con ?? en lugar de la aserción non-null !, que se limita a mover el fallo a otro lugar. "Property has no initializer" (strictPropertyInitialization): inicializa en el constructor en lugar de recurrir a ! sobre el campo. Vigila también la trampa ?? frente a ||: port || 3000 reemplaza también 0 y "", mientras que port ?? 3000 solo reemplaza null y undefined.
interface Settings { retries?: number }
function resolveRetries(s: Settings): number {
const bad = s.retries || 3;
const good = s.retries ?? 3;
return good;
}
const names = ["Ada", "Linus"];
const first = names[0];
const upper = first?.toUpperCase() ?? "N/A";Más allá del agregado, tres opciones merecen una discusión en equipo. noUncheckedIndexedAccess añade undefined a cada acceso indexado (arr[i], dict[key]): más seguro, pero verboso en código de manipulación de arrays; muchos equipos lo adoptan solo en proyectos nuevos. exactOptionalPropertyTypes distingue "propiedad ausente" de "propiedad establecida en undefined", crucial para los patches. skipLibCheck omite la comprobación de los archivos .d.ts de tus dependencias: un compromiso deliberado entre tiempo de build y detección de conflictos entre librerías.
"strict": true en tsconfig.json?retries?: number establecido en 0, ¿cuál es la diferencia entre retries || 3 y retries ?? 3?// @ts-expect-error en lugar de // @ts-ignore para marcar la deuda de tipado?