O que é strict mode, afinal?
strict: true não é uma flag única — é um atalho que ativa um conjunto de verificações. Entender cada uma delas transforma o strict mode de obstáculo em ferramenta.
- strictNullChecks — null e undefined são tipos distintos
- noImplicitAny — toda variável precisa de tipo explícito ou inferível
- strictFunctionTypes — verificação covariante/contravariante em funções
- strictBindCallApply — tipos corretos para .bind(), .call(), .apply()
- strictPropertyInitialization — propriedades de classe devem ser inicializadas
- noImplicitThis — this em funções precisa de tipo explícito
- useUnknownInCatchVariables — catch(err) vira unknown, não any
strictNullChecks muda tudo
A flag mais impactante é strictNullChecks. Sem ela, null e undefined são assignáveis a qualquer tipo. Com ela, você é forçado a tratar casos onde um valor pode não existir — e é exatamente onde 90% dos bugs de runtime acontecem.
// Sem strictNullChecks — compila, mas quebra em runtime
function getLength(s: string): number {
return s.length; // TypeError se s for null
}
// Com strictNullChecks — erro de compilação
function getLength(s: string | null): number {
return s.length; // Error: Object is possibly 'null'
}
// Correto
function getLength(s: string | null): number {
return s?.length ?? 0;
}useUnknownInCatchVariables
Antes do TypeScript 4.4, o parâmetro de catch era implicitamente any. Com strict mode moderno, é unknown — o que te força a verificar o tipo antes de usar.
// any implícito (perigoso)
try {
await fetchData();
} catch (err) {
console.log(err.message); // compila, pode quebrar
}
// unknown (seguro)
try {
await fetchData();
} catch (err) {
if (err instanceof Error) {
console.log(err.message); // seguro
}
}Migrar um projeto grande para strict mode de uma vez é doloroso. Faça por módulo: ative // @ts-strict em arquivos individuais e vá migrando gradualmente.
Flags adicionais que uso neste projeto
Além do strict padrão, este projeto usa configurações extras que aumentam a segurança do tipo sem custo de performance.
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"forceConsistentCasingInFileNames": true
}
}noUncheckedIndexedAccess é minha flag favorita fora do strict. arr[0] passa a ser T | undefined, eliminando uma classe inteira de bugs com índices.
Vale o esforço?
Sim, sem dúvida. O custo upfront de corrigir os erros de tipo compensa em manutenção a longo prazo. IDEs ficam mais úteis, refactoring fica mais seguro e bugs de runtime diminuem visivelmente. Comece novos projetos sempre com strict habilitado.