DefinitelyTyped e @types

1. O que é o DefinitelyTyped e por que ele existe?

JavaScript puro não possui sistema de tipos estáticos. Quando você tenta usar uma biblioteca como lodash, express ou react em um projeto TypeScript, o compilador não sabe quais funções, parâmetros ou retornos existem. Sem definições de tipo, você perde autocompletar, verificação de erros em tempo de compilação e documentação embutida.

O DefinitelyTyped surgiu como uma solução comunitária para esse problema. Criado por Boris Yankov em 2014, é um repositório gigante no GitHub que armazena definições de tipos TypeScript para milhares de bibliotecas JavaScript. Atualmente, conta com mais de 8.000 pacotes de definição, mantidos por uma comunidade global de contribuidores.

A estrutura do repositório é simples: cada biblioteca tem seu próprio diretório com um arquivo index.d.ts (ou múltiplos arquivos) que descreve a API completa daquela biblioteca. Essas definições são então publicadas no npm sob o namespace @types/.

2. Entendendo o ecossistema @types

Quando você instala @types/express, o TypeScript automaticamente resolve os tipos para a biblioteca express. A resolução de nomes segue o padrão: @types/<nome-da-biblioteca> corresponde à biblioteca <nome-da-biblioteca>.

Existem três categorias de tipos:

  • Tipos embutidos: fornecidos pelo próprio TypeScript (ex: string, number, Array)
  • Tipos de bibliotecas: incluídos no pacote da biblioteca (ex: axios já vem com tipos)
  • Tipos de terceiros: fornecidos via @types (ex: @types/lodash)

O versionamento é crucial. Se você usa react@18.2.0, deve instalar @types/react@18.2.x. A correspondência não é exata, mas geralmente segue o padrão de versão major e minor:

// Exemplo de correspondência de versão
// package.json
{
  "dependencies": {
    "lodash": "^4.17.21"
  },
  "devDependencies": {
    "@types/lodash": "^4.17.0" // Compatível com lodash 4.x
  }
}

3. Instalação e configuração prática

A instalação é simples:

npm install --save-dev @types/express @types/lodash @types/node

O tsconfig.json controla como o TypeScript encontra esses tipos:

// tsconfig.json
{
  "compilerOptions": {
    "typeRoots": ["./node_modules/@types", "./src/types"],
    "types": ["node", "express"]
  }
}
  • typeRoots: define pastas onde o TypeScript procura por declarações de tipo
  • types: restringe quais pacotes @types são carregados (útil para projetos com muitos pacotes)

Quando usar @types vs. tipos nativos? Verifique se a biblioteca já inclui tipos:

// Bibliotecas que já vêm com tipos (não precisa de @types)
import axios from 'axios'; // axios já tem tipos incluídos
import lodash from 'lodash'; // precisa de @types/lodash

// Verifique no package.json da biblioteca se existe "types" ou "typings"

4. Como o TypeScript encontra os tipos (resolução de módulos)

O TypeScript busca tipos em uma ordem específica:

  1. Tipos locais: arquivos .d.ts no projeto (definidos por você)
  2. Tipos da biblioteca: campo types ou typings no package.json da biblioteca
  3. @types: pasta node_modules/@types

O node_modules/@types é automaticamente incluído na resolução, a menos que você configure typeRoots explicitamente.

Diferença entre as opções de configuração:

// include: arquivos que o TypeScript compila
"include": ["src/**/*"]

// files: arquivos específicos para compilar
"files": ["src/index.ts", "src/types.d.ts"]

// typeRoots: pastas para procurar declarações de tipo
"typeRoots": ["./node_modules/@types", "./src/@types"]

Exemplo prático de resolução:

// O TypeScript procura na seguinte ordem:
// 1. Arquivo local: ./types/express.d.ts
// 2. Pacote express: ./node_modules/express/index.d.ts (se tiver "types" no package.json)
// 3. @types: ./node_modules/@types/express/index.d.ts
import express from 'express';

5. Boas práticas ao usar @types em projetos

Mantenha versões sincronizadas: Use npm ls @types/react para verificar a versão instalada. Ferramentas como npm-check-updates ajudam a manter tudo atualizado.

Evite instalações desnecessárias: Verifique se a biblioteca já tem tipos antes de instalar @types:

# Verifique se o pacote já tem tipos
npm view axios types
npm view @types/axios
# Se o primeiro retornar algo, não precisa do segundo

Lide com conflitos de versão: Quando bibliotecas dependem de versões diferentes do mesmo @types:

// Exemplo de conflito: @types/react 18 vs 19
// Solução: forçar uma versão específica no package.json
"overrides": {
  "@types/react": "18.2.0"
}

Breaking changes nos tipos: Sempre leia as notas de release dos @types antes de atualizar:

// Exemplo de breaking change no @types/express
// Versão antiga:
app.use((req, res, next) => {});
// Versão nova pode exigir tipos mais específicos:
app.use((req: Request, res: Response, next: NextFunction) => {});

6. Quando e como contribuir com o DefinitelyTyped

Contribuir é simples e bem-vindo. O processo típico:

  1. Encontre o pacote: Vá até types/<nome-do-pacote> no repositório DefinitelyTyped
  2. Edite os tipos: Modifique o arquivo index.d.ts
  3. Teste localmente: Execute npm test no diretório do pacote

Estrutura básica de um arquivo .d.ts:

// types/minha-biblioteca/index.d.ts
declare module 'minha-biblioteca' {
  export function saudacao(nome: string): string;
  export interface Config {
    debug: boolean;
    timeout: number;
  }
  export function iniciar(config: Config): void;
}

Testes no DefinitelyTyped incluem:

  • tslint: verifica consistência de estilo
  • Compilação cruzada: testa com múltiplas versões do TypeScript
  • Testes de uso: arquivos .ts que usam a biblioteca e devem compilar sem erros

7. Alternativas e cenários especiais

Quando criar seus próprios tipos: Se a biblioteca é interna ou muito específica, crie um arquivo .d.ts local:

// src/types/minha-lib.d.ts
declare module 'minha-lib' {
  export function calcular(x: number, y: number): number;
}

Bibliotecas sem @types: Use declare module para tipagem rápida:

// src/declarations.d.ts
declare module 'biblioteca-antiga' {
  const conteudo: any;
  export default conteudo;
}

O futuro: Cada vez mais bibliotecas estão migrando para TypeScript nativo. Bibliotecas como zod, trpc e prisma já nascem com tipos perfeitos. O DefinitelyTyped continuará importante para bibliotecas legadas, mas a tendência é que o ecossistema se torne auto-suficiente em tipos.


Referências