Pesquisa de site

javascript - typescript: usando arquivos de declaração em um projeto TypeScript para expor tipos globalmente


Recentemente comecei a trabalhar com TypeScript. Tenho um projeto em TypeScript configurado que possui muitos componentes React escritos em TypeScript. Esses componentes em TypeScript geralmente exportam o próprio componente e, para tornar o desenvolvimento mais conveniente, extraí todos os tipos necessários por esse componente para um arquivo separado. Normalmente, você teria que importar esses tipos no seu componente para usá-los, mas como isso era trabalhoso, alguém da equipe teve a ideia de nomear esse arquivo separado contendo os tipos como types.d.ts (ou qualquer outro nome.d.ts). Isso torna os tipos disponíveis globalmente em todo o projeto, sem precisar importar explicitamente os tipos em nenhum lugar.

Agora, eu entendo que os arquivos de declaração de tipo são necessários apenas no caso de eu estar consumindo um componente JavaScript em meu projeto TypeScript, e se eu quiser que a verificação de tipo funcione para esse componente JavaScript. Nesse caso, eu posso obter o arquivo de declaração de tipo de fora (como, DefinitelyTyped), ou posso criar um arquivo de declaração local. Não é para isso que estou usando um arquivo de declaração aqui.

Mas eu gostaria de entender quais são os problemas com esse uso?

  • É errado expor todos os tipos globalmente (Por favor, note que a maioria desses tipos é necessária apenas internamente pelo componente, apenas alguns são necessários por outros componentes que consomem este componente)?
  • Vai haver algum problema com o compilador ou com a configuração do TypeScript por causa disso?
  • Eu li sobre uma opção de compilador que gera os arquivos de declaração, essa configuração pode interferir nisso?

NOTA: Este arquivo separado, que é nomeado como d.ts, na verdade não segue nenhuma diretriz específica que possa ser exigida para arquivos de declaração. Ele apenas possui algumas declarações de interface comuns

Resposta #1

Algumas observações:

  • em um arquivo .ts (ou um arquivo d.ts), se não houver exportação de nível superior, ele seria considerado um script global (semelhante a como isso funciona no javascript) e tudo no script estaria disponível globalmente. É assim que os tipos são expostos globalmente no meu caso (novamente, não precisa ser um arquivo .d.ts)

  • se você tiver um arquivo ts e um arquivo d.ts com o mesmo nome, o compilador ignora o arquivo d.ts e é por isso que não é possível expor tipos para Component.tsx usando Component.d.ts (você precisaria dar outro nome ao arquivo d.ts)

  • ao importar um módulo externo sem informações de tipo, o typescript sugere adicionar um arquivo d.ts com declare module moduleName, em vez disso, você também pode simplesmente adicionar um arquivo .d.ts normal com uma exportação de nível superior dentro de moduleName/index.d.ts

Então, para responder às minhas perguntas:

  • Não seria errado expor todos os tipos usados globalmente dentro da sua aplicação, mas então você precisa se preocupar com qualquer conflito de namespace/nome. Nesse caso, usar um arquivo d.ts não é obrigatório, essa configuração funcionaria igualmente com um arquivo .ts expondo os tipos globalmente. Outra maneira de conseguir isso seria exportar os tipos dos arquivos respectivos e importá-los onde for necessário.

  • nesta configuração, o único problema com o compilador que pode surgir é quando o arquivo .d.ts tem o mesmo nome do arquivo .ts, caso em que o arquivo .ts iria sobrescrever e os tipos do .d.ts não estariam disponíveis globalmente.

  • o compilador gera os arquivos de declaração a partir de arquivos ts, e isso é principalmente necessário se você precisar publicar seus tipos. No nosso caso, os tipos são internos e realmente não precisaremos gerar as declarações. Nosso uso, como discutido, não depende do arquivo ser um arquivo de declaração, ele funcionará igualmente bem em um arquivo .ts e não deveríamos estar usando arquivos .d.ts para isso. Então, não, não haveria nenhum impacto.

Resposta #2

A equipe TS é contra essa prática, TS vê os arquivos .d.ts apenas como associados ao arquivo .js para fornecer segurança de tipo.

Isso também tem poucos problemas

  1. Não haverá verificação de tipo para este arquivo se você usar a opção skipLibCheck no seu tsconfig

  2. Arquivos .d.ts são para colocar coisas no escopo global ou alterar escopos globais em seus projetos, então digamos que você escreva algum tipo em .d.ts, ele estará disponível para todos os componentes no seu código.

  3. Digamos que existam vários arquivos .d.ts no seu código e, se houver múltimas interfaces com o mesmo nome, elas irão se mesclar (no caso de interface) e podem causar erros inesperados.

Há também um tópico no repositório do TypeScript para essa mesma discussão https://github.com/microsoft/TypeScript/issues/52593