Augmentação de módulo TypeScript e tratamento de arquivos JavaScript aninhados
Aprenda o básico sobre a augmentação de módulo em TypeScript e como adicionar definições de tipos para arquivos JavaScript aninhados.
O TypeScript tem sido uma adição valiosa ao ecossistema JavaScript por mais de uma década, ganhando popularidade devido à sua capacidade de fornecer segurança de tipos para o código JavaScript.
Tipos para pacotes JavaScript
Por compatibilidade retroativa e flexibilidade, o TypeScript permite que os autores de pacotes forneçam definições de tipos para seus pacotes JavaScript. Tais definições de tipos geralmente são armazenadas no repositório "DefinitelyTyped". Você pode usar o escopo @types
para instalar essas definições de tipos; por exemplo, @types/react
é a definição de tipo para o pacote React.
Após instalar essas definições de tipos, você pode usar o pacote com confiança na segurança de tipos. Aqui está um exemplo de definição de um componente React com segurança de tipos:
Augmentação de módulo
Embora a maioria dos pacotes JavaScript populares tenha definições de tipos prontamente disponíveis no escopo @types
, alguns pacotes podem carecer de definições de tipos ou ter definições desatualizadas. Nesses casos, o TypeScript fornece um recurso poderoso conhecido como "augmentação de módulo" para adicionar definições de tipos a esses pacotes. Vejamos um exemplo:
Agora você pode usar essa definição de tipo augmentada no seu código:
A augmentação de módulo não só permite que você adicione definições de tipos para pacotes, mas também expanda definições de tipos existentes. Por exemplo, você pode adicionar uma nova propriedade ao objeto window
:
E usá-la no seu código:
Em um post anterior, discutimos um problema de tipos na biblioteca React Router, e tivemos que superar o impacto expandindo e augmentando o tipo existente por meio de um arquivo de declaração personalizado.
Lembre-se de que ao usar augmentação de módulo, é crucial garantir a precisão de suas definições de tipos inspecionando de perto o código-fonte JavaScript. Definições de tipos incorretas podem levar a erros em tempo de execução. No exemplo acima, a propriedade window.foo
deve ser uma string que existe no objeto window
.
Augmentação global
Às vezes, você pode encontrar scripts que introduzem variáveis globais, e pode querer fornecer definições de tipos para essas variáveis globais para usá-las em seu código TypeScript. Por exemplo, se você tiver um script que define uma variável global chamada __DEV__
:
Você pode adicionar definições de tipos para essa variável global assim:
Agora você pode usá-la em seu código TypeScript:
Combinando augmentação de módulo e augmentação global, você pode até mesmo estender definições de tipos para protótipos JavaScript. No entanto, isso geralmente não é recomendado, pois pode poluir o escopo global.
O poder da augmentação de módulo permite tais extensões, mas use com cautela para evitar a poluição do escopo global.
Arquivos JavaScript aninhados
Nos exemplos mencionados anteriormente, assumimos que as importações poderiam ser resolvidas através do arquivo de entrada do pacote. No entanto, alguns pacotes exportam arquivos JavaScript aninhados sem definições de tipos correspondentes. Considere um pacote chamado foo
com a seguinte estrutura:
O pacote foo
exporta o arquivo index.js
como ponto de entrada e também exporta o diretório bar
.
Para augmentar as definições de tipos para o pacote foo
, você pode criar um arquivo foo.d.ts
:
No entanto, se você tentar importar o arquivo baz.js
no TypeScript, encontrará um erro:
Para augmentar as definições de tipos para o arquivo baz.js
, você precisa criar um arquivo baz.d.ts
separado:
Isso garante que o TypeScript possa localizar o módulo e suas definições de tipos associadas:
Para manter as definições de tipos organizadas, você pode imitar a estrutura do pacote em seus arquivos de definição de tipos:
Essa abordagem mantém seu código TypeScript estruturado e seguro em relação a tipos, mesmo ao lidar com arquivos JavaScript aninhados.