A maioria dos projetos TypeScript que analiso tem "strict": true no tsconfig.json, mas também tem // @ts-ignore espalhados pelo código, any em lugares estratégicos, e engenheiros que não sabem o que o strict mode protege.
Strict mode não é um conjunto arbitrário de restrições para irritar o compilador. São flags, cada uma capturando uma categoria de bug que acontece em runtime. Entender o que cada flag faz muda "o TypeScript me obrigou a fazer isso" para "o TypeScript me impediu de cometer esse erro".
O que "strict": true habilita
"strict": true é um atalho para habilitar um conjunto de flags. Vamos pelo que importa:
strictNullChecks
A mais importante. Sem ela, null e undefined são assignáveis a qualquer tipo. Com ela, você precisa lidar com a possibilidade de ausência.
// Sem strictNullChecks: compila, pode explodir em runtime
function getUser(id: string): User {
return db.find(id) // pode retornar undefined
}
const name = getUser('123').name // TypeError: Cannot read property 'name' of undefined
// Com strictNullChecks: erro em tempo de compilação
function getUser(id: string): User | undefined {
return db.find(id)
}
const user = getUser('123')
const name = user?.name // forçado a lidar com o undefined
noImplicitAny
Força a tipagem explícita quando o TypeScript não consegue inferir o tipo. Sem isso, parâmetros de função sem tipo viram any sem aviso, e você perde toda a proteção do sistema de tipos.
// ❌ Sem noImplicitAny: param é `any` implicitamente
function process(data) { // param: any
return data.value.toUpperCase() // sem verificação
}
// ✅ Com noImplicitAny: você declara a intenção
function process(data: { value: string }) {
return data.value.toUpperCase()
}
strictFunctionTypes
Garante verificação de tipos correta em callbacks. Sem ela, funções são verificadas bivariantly, o que pode deixar bugs de tipo passar.
// strictFunctionTypes captura este bug
type Handler = (event: MouseEvent) => void
const myHandler: Handler = (event: Event) => {} // ❌ Erro correto: MouseEvent é mais específico
strictPropertyInitialization
Garante que propriedades de classe sejam inicializadas no constructor. Previne leituras de propriedades undefined que parecem definidas.
class UserService {
private db: Database // ❌ Erro: não inicializado no constructor
constructor() {
// esqueceu de inicializar db
}
}
// ✅ Correto
class UserService {
private db: Database
constructor(db: Database) {
this.db = db
}
}
Flags que não estão no strict mas que você deveria habilitar
noUncheckedIndexedAccess
Acessos a arrays e objetos com index retornam T | undefined ao invés de T. Previne um dos bugs mais comuns: assumir que um index sempre existe.
// tsconfig.json
{ "compilerOptions": { "noUncheckedIndexedAccess": true } }
const items = ['a', 'b', 'c']
const first = items[0] // tipo: string | undefined (não string)
const safe = first?.toUpperCase() // forçado a verificar
exactOptionalPropertyTypes
Diferencia { prop?: string } (prop pode estar ausente) de { prop: string | undefined } (prop presente mas undefined). São coisas diferentes, e sem essa flag, TypeScript trata igual.
Como migrar um projeto legado para strict
Habilitar strict de uma vez num projeto grande não é prático. A estratégia que funciona:
- Habilite
"strict": truee use// @ts-ignoreem tudo que quebrar (sim, temporariamente) - Crie uma regra de lint que proíbe novos
// @ts-ignore, o legado pode existir, o novo não - Gradualmente, resolva os
@ts-ignorearquivo por arquivo, priorizando os mais críticos
Isso dá o benefício imediato de strict no código novo enquanto o legado é corrigido aos poucos.
Por que não desabilitar o que você não entende
Cada vez que você adiciona // @ts-ignore, as any, ou desabilita uma flag, você está dizendo: "Confio em mim mesmo mais do que no compilador aqui." Às vezes isso é legítimo, ao trabalhar com bibliotecas mal tipadas, por exemplo.
Na maioria das vezes, é fuga. E o TypeScript está te protegendo de algo que vai explodir em runtime. Talvez não amanhã. Talvez em 6 meses. Talvez em produção numa sexta às 23h.
Quando você não entende por que o TypeScript está reclamando, a resposta certa é entender, não silenciar. Usar TypeScript e usar TypeScript bem são coisas diferentes.
Curtiu o conteúdo?
Construo produtos web e soluções com IA do jeito certo — arquitetura sólida, código sustentável e entrega real.
Vamos conversar