Voltar ao Blog
    TypeScript
    Frontend

    TypeScript Strict Mode: Vale o Esforço?

    strict: true no tsconfig assusta no começo. Depois que você entende o que cada flag faz, é difícil programar sem ela.

    Publicado em ·7 min de leitura·por Bernardo Gomes

    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.

    typescript
    // 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.

    typescript
    // 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.

    json
    {
      "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.