Como você produz um arquivo de definição de “tipagem” .d.ts a partir de uma biblioteca JavaScript existente?
-
12-12-2019 - |
Pergunta
Estou usando muitas bibliotecas próprias e de terceiros.Vejo que o diretório "typings" contém alguns para Jquery e WinRT...mas como eles são criados?
Solução
Existem algumas opções disponíveis, dependendo da biblioteca em questão, como está escrita e do nível de precisão que você procura.Vamos revisar as opções, em ordem decrescente de conveniência.
Talvez já exista
Sempre marque DefinitelyTyped (https://github.com/DefinitelyTyped/DefinitelyTyped) primeiro.Este é um repositório da comunidade cheio de literalmente milhares de arquivos .d.ts e é muito provável que o que você está usando já esteja lá.Você também deve verificar TypeSearch (https://microsoft.github.io/TypeSearch/) que é um mecanismo de busca para arquivos .d.ts publicados pelo NPM;isso terá um pouco mais de definições do que DefinitelyTyped.Alguns módulos também estão enviando suas próprias definições como parte de sua distribuição NPM, portanto, veja também se esse é o caso antes de tentar escrever as suas próprias.
Talvez você não precise de um
TypeScript agora suporta o --allowJs
flag e fará mais inferências baseadas em JS em arquivos .js.Você pode tentar incluir o arquivo .js em sua compilação junto com o --allowJs
configuração para ver se isso fornece informações de tipo boas o suficiente.O TypeScript reconhecerá coisas como classes no estilo ES5 e comentários JSDoc nesses arquivos, mas poderá falhar se a biblioteca se inicializar de maneira estranha.
Comece com --allowJs
Se --allowJs
deu resultados decentes e você deseja escrever um arquivo de definição melhor, você pode combinar --allowJs
com --declaration
para ver o "melhor palpite" do TypeScript sobre os tipos da biblioteca.Isso lhe dará um ponto de partida decente e pode ser tão bom quanto um arquivo de autoria manual se os comentários do JSDoc forem bem escritos e o compilador for capaz de encontrá-los.
Comece com dts-gen
Se --allowJs
não funcionou, você pode querer usar dts-gen (https://github.com/Microsoft/dts-gen) para obter um ponto de partida.Esta ferramenta usa a forma de tempo de execução do objeto para enumerar com precisão todas as propriedades disponíveis.No lado positivo, isso tende a ser muito preciso, mas a ferramenta ainda não oferece suporte à extração de comentários JSDoc para preencher tipos adicionais.Você executa isso assim:
npm install -g dts-gen
dts-gen -m <your-module>
Isto irá gerar your-module.d.ts
na pasta atual.
Aperte o botão Soneca
Se você quiser fazer tudo mais tarde e ficar sem tipos por um tempo, no TypeScript 2.0 agora você pode escrever
declare module "foo";
que vai deixar você import
o "foo"
módulo com tipo any
.Se você tem um problema global com o qual deseja lidar mais tarde, basta escrever
declare const foo: any;
que lhe dará um foo
variável.
Outras dicas
Você pode usar tsc --declaration fileName.ts
como Ryan descreve, ou você pode especificar declaration: true
sob compilerOptions
na tua tsconfig.json
supondo que você já tenha tido um tsconfig.json
sob seu projeto.
A melhor maneira de lidar com isso (se um arquivo de declaração não estiver disponível em definitivamente formado ) é paraEscreva declarações apenas para as coisas que você usa em vez de toda a biblioteca.Isso reduz muito o trabalho - e, além disso, o compilador está lá para ajudar a reclamar sobre métodos ausentes.
Como diz Ryan, o compilador tsc tem uma opção --declaration
o que gera um .d.ts
arquivo de um .ts
arquivo.Observe também que (exceto bugs) o TypeScript deve ser capaz de compilar Javascript, para que você possa passar o código javascript existente para o compilador tsc.
Conforme descrito em http://channel9.msdn.Com / Posts / Anders-Hejlsberg-Steve-Lucco-e-Luke-Hoban-Inside-Typanict A 00:33:52 Eles haviam construído uma ferramenta para converter o Webidl e o Winrt Metadados em d.TS typyscript
Aqui está um PowerShell que cria um único arquivo de definição TypeScript, uma biblioteca que inclui vários *.js
arquivos com JavaScript moderno.
Primeiro, altere todas as extensões para .ts
.
Get-ChildItem | foreach { Rename-Item $_ $_.Name.Replace(".js", ".ts") }
Segundo, use o compilador TypeScript para gerar arquivos de definição.Haverá vários erros do compilador, mas podemos ignorá-los.
Get-ChildItem | foreach { tsc $_.Name }
Por fim, combine todos os *.d.ts
arquivos em um index.d.ts
, removendo o import
declarações e removendo o default
de cada declaração de exportação.
Remove-Item index.d.ts;
Get-ChildItem -Path *.d.ts -Exclude "Index.d.ts" | `
foreach { Get-Content $_ } | `
where { !$_.ToString().StartsWith("import") } | `
foreach { $_.Replace("export default", "export") } | `
foreach { Add-Content index.d.ts $_ }
Isso termina com um único e utilizável index.d.ts
arquivo que inclui muitas das definições.
Eu procuraria um mapeamento existente de suas bibliotecas de 3ª parte JS que suportam o script # ou o Shardkit.Os usuários desses compiladores cruzados C # para .js enfrentarão o problema que você agora enfrentou e pode ter publicado um programa de código aberto para digitalizar sua 3ª parte lib e converter em classes de esqueleto C #.Em caso afirmativo, hackear o programa do scanner para gerar o tipografia no lugar de C #.
Falha disso, traduzir uma interface pública C # para sua 3ª parte lib em definições typycript pode ser mais simples do que fazer o mesmo lendo o JavaScript de origem.
Meu interesse especial é o ExtJs Ria Framework da Sencha e sei que houve projetos publicados para gerar uma interpretação C # para script # ou SharpKit
Ao criar sua própria biblioteca, você pode criar *.d.ts
arquivos usando o tsc
(Compilador TypeScript) da seguinte forma:(supondo que você esteja construindo sua biblioteca para o dist/lib
pasta)
tsc -d --declarationDir dist/lib --declarationMap --emitDeclarationOnly
-d
(--declaration
):gera o*.d.ts
arquivos--declarationDir dist/lib
:Diretório de saída para arquivos de declaração gerados.--declarationMap
:Gera um mapa de origem para cada arquivo ‘.d.ts’ correspondente.--emitDeclarationOnly
:Emita apenas arquivos de declaração ‘.d.ts’.(sem JS compilado)
(Veja o documentos para todas as opções do compilador de linha de comando)
Ou por exemplo no seu package.json
:
"scripts": {
"build:types": "tsc -d --declarationDir dist/lib --declarationMap --emitDeclarationOnly",
}
e então execute: yarn build:types
(ou npm run build:types
)