Liguei strict mode num codebase NestJS legado semana passada. 847 erros. Fiquei olhando pro terminal por um minuto inteiro antes de fechar o notebook e ir fazer café. Precisava processar o luto.
Cada erro daqueles apontava um problema real. Os bugs já estavam lá, escondidos atrás de tipo frouxo, prontos pra estourar em produção.
Os erros mais comuns eram propriedade opcional acessada sem check e função que retornava undefined pra quem esperava um valor. Também tinha objeto any atravessando três camadas de abstração até ninguém mais saber seu formato.
Ligar strictNullChecks sozinho levantou uns 200 problemas. Cada um era crash potencial em runtime esperando o input errado na hora errada. Aquele tipo de bug que aparece 2h da manhã num sábado quando um usuário maluco manda formulário com string vazia onde tu esperava número.
strictPropertyInitialization encontrou classes com propriedade que era "com certeza atribuída no construtor", só que vinha de um método init() chamado depois da construção. Talvez. Se os astros se alinhassem e Mercúrio não estivesse retrógrado.
Passei a tratar tipo como contrato. Quando escrevo a assinatura de uma função, penso no que acontece se o input for null. Quando defino uma interface, separo os campos realmente opcionais daqueles que eu deixei assim por preguiça de tornar obrigatórios.
A migração levou três dias dolorosos e tediosos adicionando null check e corrigindo type assertion. Desde então, tivemos zero bug de tipo em produção. O compilador pega tudo em build time.
Liga strict mode no dia um de qualquer projeto. Se tu tá herdando um codebase sem ele, separa uma semana e faz. Dói a ponto de tu questionar tuas escolhas de carreira, mas achar esses bugs em produção dói muito mais.
Pra mim, TypeScript strict virou um requisito de qualidade do projeto.