@types/* em dependencies ou devDependencies: principais erros

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que a pergunta sobre @types/* atormenta até desenvolvedores experientes?



Você já passou uma hora debugando um erro que, no final, se resumia ao posicionamento incorreto do pacote @types/* no package.json? Se sim — você não está sozinho. A pergunta «How do I decide whether @types/* goes into dependencies or devDependencies?» acumulou milhares de visualizações no Stack Overflow e se tornou uma verdadeira dor de cabeça para a comunidade TypeScript.



Parece simples, não? Colocar os tipos em devDependencies e pronto. Mas não é bem assim. Quando seu projeto começa a crescer, bibliotecas de terceiros, monorepositórios e pipelines de CI/CD são adicionados, e o posicionamento incorreto dos tipos pode levar a erros fatais de build, quedas inesperadas em produção ou, pior ainda, à perda silenciosa da tipagem.



Neste artigo, vamos analisar os 5 erros mais comuns ao trabalhar com @types/*, aprender a tomar a decisão correta com base em cenários reais e criar um checklist que o protegerá de problemas. Pronto? Vamos lá!



Erro nº1: «Todos os @types/* sempre vão em devDependencies» — um mito que quebra builds



O conselho mais popular na internet é: «Tipos não são código em runtime, portanto devem estar sempre em devDependencies». E isso em 90% dos casos é realmente verdade. Mas há uma exceção importante que muitos esquecem.



Quando devDependencies é a escolha correta

Se você está escrevendo uma aplicação (servidor web em Express, frontend React, utilitário de linha de comando), então todos os @types/* podem ir tranquilamente para devDependencies. Seu usuário final não compila TypeScript — ele executa o JavaScript já compilado. Os tipos são necessários apenas para você durante o desenvolvimento.



// Exemplo para uma aplicação em Express{  "devDependencies": {    "@types/express": "^4.17.21",    "@types/node": "^20.11.0",    "typescript": "^5.3.3"  }}


Quando devDependencies é um erro fatal

Agora imagine: você está desenvolvendo uma biblioteca que exporta tipos TypeScript para consumidores externos. Se os tipos da sua biblioteca dependem de @types/express e você o colocou em devDependencies, o usuário que instalar sua biblioteca não receberá esses tipos automaticamente. E a IDE dele começará a mostrar sublinhados vermelhos.



// ❌ Incorreto para uma biblioteca que exporta tipos{  "devDependencies": {    "@types/express": "^4.17.21" // O usuário não verá esses tipos!  }}

// ✅ Correto{ "dependencies": { "@types/express": "^4.17.21" // Os tipos estarão disponíveis para os consumidores }}


Regra de ouro: Se sua biblioteca reexporta tipos de um pacote @types/* ou os utiliza em uma API pública, esse pacote deve estar em dependencies. Se os tipos são usados apenas internamente — devDependencies.



Erro nº2: Ignorar a diferença entre «uso no código» e «uso nos tipos»



Muitos desenvolvedores confundem: «Eu importo Request de express, então express deve estar em dependencies». Isso é verdade para o próprio pacote express, mas não para seus tipos.



Vamos analisar com um exemplo concreto. Existem três cenários de uso do pacote @types/lodash:



  • Cenário A: Você escreve import _ from 'lodash' e usa _.chunk(). Os tipos são necessários apenas para compilação — devDependencies.
  • Cenário B: Você cria uma função function mySort(arr: T[]): T[] e internamente usa _.orderBy. Os tipos não são expostos externamente — devDependencies.
  • Cenário C: Você escreve export function proc

Blogs

Book Recommendations