O erro «invisível» que todo desenvolvedor TypeScript conhece
Você está escrevendo código em TypeScript, tudo corre bem, mas de repente — uma linha vermelha ondulada sob o import. O compilador informa algo assustador: Could not find a declaration file for module 'module-name'. '/path/to/module-name.js' implicitly has an 'any' type. Se você já trabalhou com TypeScript, certamente já encontrou esta mensagem. Ela aparece quando você tenta importar um módulo JavaScript para o qual não existe um arquivo de declaração (geralmente com a extensão .d.ts).
No Stack Overflow, esta pergunta acumulou milhares de visualizações. E não é por acaso: o problema parece complexo, embora na verdade tenha várias soluções simples e elegantes. Neste artigo, vamos analisar por que o erro ocorre e comparar quatro abordagens principais para resolvê-lo. Você aprenderá qual método escolher dependendo da situação e poderá esquecer para sempre os tipos «invisíveis».
Por que o TypeScript exige declaração?
TypeScript é uma extensão do JavaScript que adiciona tipagem estática. Quando você escreve import * as _ from 'lodash', o TypeScript precisa saber quais tipos a variável _ possui. Se não houver um arquivo .d.ts para o módulo, o compilador não consegue verificar os tipos e, por padrão, atribui ao módulo o tipo any. Isso viola o rigor da tipagem, então o TypeScript o avisa. Na verdade, não é um erro de execução, mas um aviso de compilação; no entanto, em projetos estritos (strict: true), pode bloquear a compilação.
Agora vamos às soluções. Veremos quatro abordagens, da mais simples à mais flexível.
Solução 1: Rápida e suja — declare module
A maneira mais simples é criar um arquivo de declaração manualmente. Para isso, adicione ao seu projeto um arquivo global.d.ts (ou types.d.ts) e escreva:
// global.d.tsdeclare module 'module-name';Esta linha diz ao TypeScript: «O módulo existe, mas seu tipo é any». O problema está resolvido, mas você perde todas as vantagens da tipagem. Esta abordagem é boa para protótipos rápidos ou quando o módulo é usado em um ou dois lugares. No entanto, para projetos em produção, não é a melhor escolha.
- Prós: Mínimo de código, não requer instalação de pacotes.
- Contras: O tipo
anyanula o propósito do TypeScript; se o módulo for atualizado, você não saberá sobre a mudança na API.
Solução 2: Uso de pacotes @types
Para a maioria dos módulos npm populares, existem pacotes separados com declarações. Por exemplo, para lodash é @types/lodash. Instale-os via npm ou yarn:
npm install --save-dev @types/lodashDepois disso, o TypeScript encontrará automaticamente as declarações e o erro desaparecerá. Se você usa TypeScript 2.0+, ele próprio procura pela pasta @types. Esta é a forma padrão e recomendada.
- Prós: Tipagem completa, suporte da comunidade, atualizações automáticas.
- Contras: Nem todos os módulos possuem
@types(por exemplo, para bibliotecas menos conhecidas).
Como verificar se existem tipos? Acesse a página npm ou execute npm info @types/nome-do-módulo. Se o pacote não for encontrado, passe para a próxima solução.
Solução 3: Ativação de allowJs e checkJs
Se você está escrevendo um projeto que mistura TypeScript e JavaScript, pode permitir que o compilador verifique arquivos JS. Para isso, no tsconfig.json adicione:
{ "compilerOptions": { "allowJs": true, "checkJs": false }}A opção allowJs permite importar módulos JS em arquivos TS. Com isso, o TypeScript tentará