DEV Community

Matheus Morett for Monest

Posted on

Como Eliminamos 4.041 Erros de TypeScript em 6 Meses

Quando assumi como Head de Tecnologia da Monest em janeiro de 2025, me deparei com um cenário que muitos times de engenharia conhecem bem: TypeScript configurado com strict: false. Na prática, isso significava que nosso "TypeScript" era apenas JavaScript com extensão .ts — sem as verdadeiras garantias de tipo que tornam o TypeScript valioso.

O problema era simples de identificar: código como object.value onde object poderia ser undefined passava tranquilamente no build, só para explodir em runtime. Mas a solução? Essa era outra história.

O Desafio: 4.041 Erros de Uma Vez

Quando finalmente ativamos strict: true para avaliar a situação, fomos recebidos por uma parede vermelha no VSCode: 4.041 erros de TypeScript.

Ninguém consegue resolver 4.041 erros do dia para a noite. E mesmo que conseguisse, o risco de quebrar funcionalidades críticas em produção — especialmente em uma startup de cobrança por IA como a Monest — era inaceitável.

Precisávamos de uma estratégia diferente.

Nossa Abordagem: Migração Gradual e Sustentável

1. Strict em Dev, Permissivo em Prod

A primeira decisão foi aparentemente contraditória, mas fundamental:

  • strict: true em desenvolvimento — para que os erros aparecessem na nossa cara enquanto editávamos arquivos
  • ⚠️ strict: false em deploy — para que a build funcionasse mesmo com erros pendentes

Isso nos deu visibilidade do problema sem bloquear o time ou comprometer entregas.

2. Uma GitHub Action para Criar Accountability

Criamos uma GitHub Action que contava os erros de TypeScript a cada PR. A regra era simples: cada PR precisava reduzir pelo menos 1 erro.

Comentário no GitHub dizendo que foram removidos erros o suficiente

Não importava se você estava trabalhando em uma nova feature ou em um bugfix — você tinha que resolver ao menos um débito técnico de TypeScript. Sem exceções.

3. A Regra de Ouro: Produção em Primeiro Lugar

Estabelecemos uma regra de ouro para guiar decisões difíceis:

"O sistema funciona em produção. Na dúvida entre alterar o código ou o tipo, altere o tipo."

Essa diretriz foi crucial. Em vez de tentar "corrigir" código que funcionava (e potencialmente introduzir bugs), priorizamos ajustar as definições de tipo para refletir a realidade do código existente. Refatorações podiam vir depois, quando entendêssemos melhor cada parte do sistema.

Nem tudo foi perfeito nessa jornada. Tivemos um deploy que acabou quebrando produção — ironicamente, o erro foi justamente fazer o oposto da nossa regra de ouro: confiamos no tipo (que estava errado) em vez do código (que funcionava). Foi um lembrete valioso de que tipos são ferramentas para nos ajudar a entender o código, não verdades absolutas sobre ele.

Esse incidente reforçou ainda mais a importância da nossa abordagem cautelosa e incremental.

4. Visibilidade e Celebração do Progresso

Incorporamos na nossa reunião de engineering all-hands o ritual de ver quantos erros tínhamos eliminado no mês. Transformamos o que poderia ser uma tarefa chata em um indicador de progresso coletivo.

Gráfico em linha da diminuição de erros de TypeScript

Ver aquele número caindo mês a mês criou um senso de conquista compartilhada.

5. Atenção Especial para Código Crítico

Para arquivos sensíveis — como nossa lógica de geração de acordos, o coração da nossa plataforma — criamos tickets específicos. Essas partes do código mereciam atenção focada e revisão cuidadosa, não podiam ser tratadas como "apenas mais um erro para resolver".

Os Resultados

Mantivemos uma média de 800 erros removidos por mês.

Em 6 meses, chegamos a zero erros de TypeScript.

Hoje, em novembro de 2025, arquivos vermelhos com erros de TypeScript são coisa do passado na Monest. Mais importante: ganhamos:

  • Confiança — refatorações são menos arriscadas
  • Produtividade — o autocomplete realmente funciona
  • Qualidade — pegamos erros em tempo de desenvolvimento, não em produção
  • Onboarding — novos engenheiros entendem o código mais rapidamente

Lições Aprendidas

1. Débito técnico não se resolve em um sprint heroico

Tentativas de "resolver tudo de uma vez" geralmente falham. Progresso consistente e incremental vence.

2. Automação cria disciplina

A GitHub Action transformou a resolução de débito técnico de "quando der tempo" para "sempre, um pouco por vez".

3. Visibilidade gera engajamento

Compartilhar o progresso publicamente nas all-hands criou senso de propriedade coletiva.

4. Produção não pode esperar perfeição

A configuração híbrida (strict em dev, permissivo em prod) nos deu o melhor dos dois mundos: visibilidade sem bloqueio.

5. Tipos servem o código, não o contrário

Nosso único incidente em produção nos ensinou: quando os tipos contradizem código que funciona, questione os tipos primeiro.

Top comments (0)