en
· 4 min de leitura

Strict mode é o code review mais barato que você vai ter

Um revisor que lê cada linha, a cada tecla, nunca cansa e não tem ego. Custa uma linha no tsconfig.

fullstacktypescript

Já li muitas diretrizes de code review. A maioria pede ao revisor para checar coisas que um compilador checaria em um milissegundo: um valor que pode ser null, um argumento na posição errada, um caso que ninguém tratou. Humanos são ruins nisso. Cansam, passam os olhos, confiam no autor. O compilador não.

Ligar o strict mode no TypeScript é contratar um revisor que lê cada linha de cada arquivo a cada tecla, nunca pula um caso e não se importa que o prazo seja amanhã. O preço é uma linha no tsconfig e algumas semanas de limpeza honesta. É o melhor negócio do software.

O que o strict liga de fato

A flag strict é um pacote. A que mais importa é strictNullChecks, que faz null e undefined serem tipos separados, de modo que uma função que retorna um usuário possivelmente ausente não pode ser usada como se o usuário estivesse sempre lá. Quase todo null pointer de produção que rastreei em auditoria veio de uma base de código onde isso estava desligado.

noImplicitAny proíbe o compilador de desistir em silêncio e tipar algo como any. strictFunctionTypes faz parâmetros de callback serem checados na direção certa. useUnknownInCatchVariables tipa o erro capturado como unknown em vez de any, então você precisa checar o que é antes de ler a mensagem. strictPropertyInitialization insiste que campos de classe sejam definidos no construtor.

Depois existem as flags que não estão no pacote e deveriam estar. noUncheckedIndexedAccess faz um acesso a array ou record retornar um valor possivelmente undefined, que é o que ele é. exactOptionalPropertyTypes distingue uma propriedade ausente de uma definida como undefined. noFallthroughCasesInSwitch e noImplicitOverride pegam dois dos erros de copiar e colar mais comuns. Ligo todas no primeiro dia, antes de existir código para reclamar.

O que ele pega e o revisor não

O caso faltando. Um switch sobre uma união de status de pedido que trata quatro de cinco. Com checagem estrita e uma asserção de never no ramo default, adicionar um quinto status quebra o build em todo lugar onde o switch esqueceu. Um revisor humano vê um diff que adiciona um status e aprova. O compilador vê onze switches que precisam de atualização.

O opcional que não era. Um tipo de resposta de API marcou um campo como opcional porque um endpoint o omite, e agora um componente que o usa para exibição renderiza undefined. Sem checagem estrita de null isso é um espaço em branco em runtime. Com ela é um sublinhado vermelho antes do commit.

O índice que errou. Ler o primeiro elemento de um array que voltou vazio. Ler um mapa de config por uma chave que nunca foi definida. noUncheckedIndexedAccess transforma cada um desses em erro de compilação a menos que você trate a ausência, e é desconfortável por exatamente uma semana, depois da qual o código passa a ser honesto sobre suas suposições.

Ligando em uma base de código antiga

A objeção é sempre a contagem. Ligar strict em um projeto maduro produz dois mil erros e ninguém tem uma semana. A resposta é não fazer tudo de uma vez.

Habilite uma flag por vez, começando por noImplicitAny, depois strictNullChecks. Para cada uma, suprima os erros existentes com uma diretiva que inclua a referência de um ticket, e adicione uma checagem no CI de que a contagem só diminui. Código novo é strict desde o primeiro dia. Código antigo é limpo quando é tocado. Na maioria dos projetos a contagem chega a zero em um trimestre sem esforço dedicado, porque os engenheiros corrigem a supressão quando já estão no arquivo.

Project references permitem ir além: pacotes strict e pacotes lenientes no mesmo repositório, com a fronteira entre eles explícita, para que o núcleo de domínio seja strict mesmo enquanto o painel de admin legado não é.

A revisão que sobra

Strict mode não substitui a revisão humana. Ele remove a parte mecânica dela, e isso muda o que humanos revisam. Quando o revisor sabe que o compilador já checou nulidade e exaustividade, pode gastar atenção nas perguntas que só uma pessoa responde: este é o design certo, este nome significa o que diz, vamos entender isso daqui a um ano.

Essa é a revisão que vale pagar um engenheiro sênior para fazer. A outra custa uma linha em um arquivo de config, e nunca entendi por que alguém deixa desligada.