El modo strict es la opción "strict": true de tsconfig.json. Es un único interruptor para ocho opciones de comprobación de tipos que detectan any implícitos, null y undefined sin comprobar, asignaciones de funciones inseguras y campos de clase sin inicializar. En TypeScript 7, strict está activado por defecto. Así es el código que lo supera:
La salida es no user, SyntaxError y 42. Quita el : number, el ?. o la comprobación con instanceof y el archivo deja de compilar.
Cómo activarlo
{
"compilerOptions": {
"strict": true
}
}
Las opciones individuales ganan a strict, en cualquier dirección. "strict": true, "strictNullChecks": false mantiene todo excepto la comprobación de null; "strict": false, "noImplicitAny": true activa solo esa. strict también te incluye en las comprobaciones que se añadan en versiones futuras, porque las nuevas opciones de la familia strict se suman al grupo.
El strict de TypeScript no tiene nada que ver con la directiva "use strict" de JavaScript, que es un modo de ejecución. TypeScript 7 siempre genera "use strict" donde hace falta, y poner alwaysStrict: false es el error TS5108 (la opción se eliminó).
Qué detecta cada opción
| Opción | Qué informa | Error |
|---|---|---|
noImplicitAny | un parámetro o variable cuyo tipo sería any sin avisar | TS7006 Parameter 'x' implicitly has an 'any' type. |
strictNullChecks | usar un valor que puede ser null o undefined | TS18048 'u' is possibly 'undefined'. |
strictFunctionTypes | asignar una función cuyo tipo de parámetro es más estrecho de lo requerido | TS2322 |
strictBindCallApply | argumentos incorrectos en .call, .bind y .apply | TS2345 |
strictPropertyInitialization | un campo de clase que nunca se asigna | TS2564 Property 'name' has no initializer and is not definitely assigned in the constructor. |
noImplicitThis | this con tipo any implícito, como en una function anidada | TS2683 |
useUnknownInCatchVariables | usar una variable de catch antes de estrecharla (es unknown) | TS18046 'err' is of type 'unknown'. |
strictBuiltinIteratorReturn | tratar it.next().value de un iterador integrado como si siempre estuviera definido | TS2322 |
Las dos que más código cambian son noImplicitAny y strictNullChecks. Este bloque incumple las dos a propósito:
Imprime index.ts(2,17): error TS7006: Parameter 'x' implicitly has an 'any' type. y index.ts(11,13): error TS18048: 'user' is possibly 'undefined'. Sin strict, esto compila y luego falla en tiempo de ejecución con TypeError: Cannot read properties of undefined (reading 'name'). Con strict, el fallo pasa a ser un error de compilación. Las soluciones son el primer bloque de esta página.
strictFunctionTypes: por qué existe
Una función que solo maneja strings no se debe usar donde pueden llegar números. La comprobación de abajo está silenciada con @ts-expect-error para que puedas ejecutarla y ver qué evita el error:
Sin el comentario, la asignación es el error TS2322, Type '(s: string) => void' is not assignable to type 'Handler'., seguido de Types of parameters 's' and 'value' are incompatible. Queda una excepción por diseño: los parámetros de los métodos declarados con sintaxis de método (handle(value: string | number): void dentro de una interfaz) se siguen comprobando de la forma más laxa, así que shout podría asignarse a un método así sin error.
strictPropertyInitialization
Cada campo de clase debe recibir un valor en su declaración o en el constructor. Tres formas de cumplirlo:
Salida:
Account {
owner: 'Ada',
balance: 0,
history: [],
lastLogin: undefined,
sessionId: 's-1'
}
Las propiedades lastLogin y sessionId existen con el valor undefined porque los campos de clase son campos reales de JavaScript con target ES2022. El ! quita la comprobación sin añadir ninguna protección en tiempo de ejecución, así que es preferible usar las otras formas. Esta opción necesita strictNullChecks; si lo desactivas, también se desactiva ella.
Activar strict en un proyecto existente
Pasar un proyecto grande a strict de golpe puede producir cientos de errores. Como strict es el valor por defecto en TypeScript 7, actualizar un proyecto cuyo tsconfig.json nunca mencionó strict lo activa por sí solo; escribe "strict": false si necesitas el comportamiento anterior mientras migras. Un camino que mantiene la compilación en verde:
- Añade
"strict": truey desactiva las opciones con más errores, normalmente"strictNullChecks": falsey"noImplicitAny": false. - Corrige los errores que quedan, luego activa una opción más y repite.
- Para
noImplicitAny, la mayoría de las correcciones son anotaciones de parámetros. ParastrictNullChecks, añade| undefineddonde los valores pueden faltar y luego manéjalo con?.,??o unif. - Cuando una corrección tenga que esperar, pon
// @ts-expect-errorcon un motivo en la línea. A diferencia de@ts-ignore, da un error en cuanto el problema desaparece, así que la lista se reduce sola.
No recurras a as any ni a ! para silenciar errores en masa: cada uno oculta justo el bug que la opción se añadió para encontrar.
Opciones útiles que strict no incluye
Son independientes porque rechazan código que a menudo es correcto. Muchos proyectos las activan de todos modos.
| Opción | Qué hace |
|---|---|
noUncheckedIndexedAccess | arr[i] y record[key] incluyen undefined en su tipo |
exactOptionalPropertyTypes | debug?: boolean acepta una clave ausente pero no debug: undefined |
noImplicitReturns | cada camino de una función que devuelve un valor debe hacer return (TS7030) |
noImplicitOverride | un método que sobrescribe un método base debe indicar override (TS4114) |
noFallthroughCasesInSwitch | un case no vacío debe terminar con break, return o throw (TS7029) |
noUnusedLocals, noUnusedParameters | las variables y los parámetros sin usar son errores |
noPropertyAccessFromIndexSignature | las claves de una firma de índice deben usar obj["key"], no obj.key |
noUncheckedIndexedAccess es la que detecta más bugs reales. Con ella activada:
const scores = [90, 85];
const d: Record<string, number> = {};
const third: number = scores[2]; // error TS2322: Type 'number | undefined' is not assignable to type 'number'.
const c: number = d["x"]; // same error
const safe = scores[2] ?? 0; // number
for (const s of scores) { // for...of is not affected: s is number
console.log(s);
}
tsc --init en TypeScript 7 activa noUncheckedIndexedAccess y exactOptionalPropertyTypes en la configuración que genera, junto a strict.
Preguntas frecuentes
¿Qué hace el modo strict en TypeScript?
"strict": true activa un grupo de comprobaciones más estrictas: noImplicitAny, strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitThis, useUnknownInCatchVariables y strictBuiltinIteratorReturn. Juntas impiden que aparezca any sin avisar y hacen que null y undefined formen parte del sistema de tipos.
¿El modo strict está activado por defecto en TypeScript?
En TypeScript 7, sí: strict vale true por defecto, así que un proyecto sin ninguna configuración de strict tiene todas las comprobaciones estrictas. tsc --init también escribe "strict": true de forma explícita. Para desactivarlo tienes que escribir "strict": false.
¿Puedo desactivar una comprobación estricta y mantener el resto?
Sí. Las opciones individuales tienen prioridad sobre strict: { "strict": true, "strictNullChecks": false } mantiene todas las comprobaciones estrictas excepto la de null. Es la forma habitual de migrar un proyecto grande opción por opción.
¿El modo strict de TypeScript es lo mismo que "use strict" de JavaScript?
No. "use strict" es un modo de ejecución de JavaScript que cambia cómo se comporta el código. El strict de TypeScript solo cambia lo que informa el comprobador de tipos. TypeScript 7 siempre genera "use strict" en la salida que no es de módulo, y alwaysStrict: false es ahora una opción eliminada.
¿strict incluye noUncheckedIndexedAccess?
No. noUncheckedIndexedAccess, exactOptionalPropertyTypes, noImplicitReturns, noImplicitOverride y noFallthroughCasesInSwitch son opciones aparte que activas tú. tsc --init activa las dos primeras en la configuración que genera.