Bagaimana Anda menghasilkan file definisi “typings” .d.ts dari pustaka JavaScript yang ada?

192

Saya menggunakan banyak perpustakaan baik milik saya sendiri maupun pihak ketiga. Saya melihat direktori "mengetik" berisi beberapa untuk Jquery dan WinRT ... tetapi bagaimana mereka dibuat?

Hotrodmonkey
sumber

Jawaban:

232

Ada beberapa opsi yang tersedia untuk Anda tergantung pada perpustakaan yang bersangkutan, bagaimana ini ditulis, dan tingkat akurasi apa yang Anda cari. Mari kita tinjau opsi, dalam urutan keinginan yang menurun.

Mungkin Sudah Ada

Selalu periksa DefinitelyTyped ( https://github.com/DefinitelyTyped/DefinitelyTyped ) terlebih dahulu. Ini adalah repo komunitas yang penuh dengan ribuan file .d.ts dan kemungkinan besar hal yang Anda gunakan sudah ada di sana. Anda juga harus memeriksa TypeSearch ( https://microsoft.github.io/TypeSearch/ ) yang merupakan mesin pencari untuk file .d.ts yang diterbitkan NPM; ini akan memiliki sedikit lebih banyak definisi daripada DefinitelyTyped. Beberapa modul juga mengirimkan definisi mereka sendiri sebagai bagian dari distribusi NPM mereka, jadi lihat juga apakah itu masalahnya sebelum mencoba untuk menulis sendiri.

Mungkin Anda Tidak Membutuhkannya

TypeScript sekarang mendukung --allowJsflag dan akan membuat lebih banyak inferensi berbasis JS dalam file .js. Anda dapat mencoba memasukkan file .js dalam kompilasi Anda bersama dengan --allowJspengaturan untuk melihat apakah ini memberi Anda informasi jenis yang cukup. TypeScript akan mengenali hal-hal seperti kelas gaya ES5 dan komentar JSDoc dalam file-file ini, tetapi mungkin akan tersandung jika pustaka menginisialisasi dirinya dengan cara yang aneh.

Mulai Dengan --allowJs

Jika --allowJsmemberi Anda hasil yang layak dan Anda ingin menulis sendiri file definisi yang lebih baik, Anda dapat bergabung --allowJsdengan --declarationuntuk melihat "tebakan terbaik" TypeScript di jenis pustaka. Ini akan memberi Anda titik awal yang baik, dan mungkin sama bagusnya dengan file yang ditulis tangan jika komentar JSDoc ditulis dengan baik dan kompiler dapat menemukannya.

Mulai dengan dts-gen

Jika --allowJstidak berhasil, Anda mungkin ingin menggunakan dts-gen ( https://github.com/Microsoft/dts-gen ) untuk mendapatkan titik awal. Alat ini menggunakan bentuk runtime objek untuk menghitung secara akurat semua properti yang tersedia. Di sisi positifnya, ini cenderung sangat akurat, tetapi alat ini belum mendukung pengikisan komentar JSDoc untuk mengisi jenis tambahan. Anda menjalankan ini seperti ini:

npm install -g dts-gen
dts-gen -m <your-module>

Ini akan menghasilkan your-module.d.tsdi folder saat ini.

Tekan Tombol Tunda

Jika Anda hanya ingin melakukan semuanya nanti dan pergi tanpa mengetik untuk sementara waktu, di TypeScript 2.0 sekarang Anda dapat menulis

declare module "foo";

yang akan membiarkan Anda importdalam "foo"modul dengan jenis any. Jika Anda memiliki global yang ingin Anda tangani nanti, cukup tulis

declare const foo: any;

yang akan memberi Anda foovariabel.

Ryan Cavanaugh
sumber
25
Aduh ... itu akan menjadi penghalang yang signifikan untuk masuk dalam banyak kasus. Akan menyenangkan untuk memiliki alat yang bisa menghasilkan setidaknya "tebakan terbaik" berdasarkan inferensi tipe. Meskipun ini mungkin tidak optimal, setidaknya mereka bisa disetel dari waktu ke waktu.
Hotrodmonkey
7
+1 - Berita baik lebih lanjut: --declarationsmenghasilkan .jsfile dan .d.tsfile, yang berarti Anda hanya perlu menjalankan satu kompilasi.
Fenton
67
Kumpulan definisi berkualitas tinggi untuk perpustakaan populer dapat ditemukan di github.com/borisyankov/DefinitelyTyped
Boris Yankov
10
Alat 'tebakan terbaik' tidak akan lebih baik dari IntelliSense yang sudah ada di TypeScript. Manfaat dari definisi tipe adalah dalam memberikan lebih banyak informasi kepada kompiler daripada yang bisa 'ditebak'.
Boris Yankov
12
--allowJsdengan --declarationopsi tidak dapat digabungkan (diuji dalam TypeScript 1.8 dan 2.0). Jika saya mencoba, saya mendapatkan:error TS5053: Option 'allowJs' cannot be specified with option 'declaration'
Alexey
52

Anda dapat menggunakan tsc --declaration fileName.tsseperti yang dijelaskan Ryan, atau Anda dapat menentukan di declaration: truebawah compilerOptionsdengan tsconfig.jsonasumsi Anda sudah memiliki tsconfig.jsonproyek Anda.

JayKan
sumber
4
Ini adalah jawaban terbaik jika Anda mengembangkan modul 2 Sudut yang ingin Anda bagikan.
Darcy
Jika saya mencoba, tsc --declaration test.tssaya mendapatkan kesalahan Cannot find name...untuk jenis yang saya coba buat file deklarasi untuk :) Jadi saya perlu jenis sebelum saya bisa mendeklarasikannya?
Kokodoko
2
@Kokodoko, dapatkah Anda mencoba menambahkan declaration: trueke tsconfig.jsonfile Anda ?
JayKan
Terima kasih, saya hanya ingin menghasilkan * .d.ts dari * .ts.
vintproykt
16

Cara terbaik untuk mengatasi ini (jika file deklarasi tidak tersedia di DefinitelyTyped ) adalah dengan menulis deklarasi hanya untuk hal-hal yang Anda gunakan daripada seluruh perpustakaan. Ini mengurangi pekerjaan banyak - dan juga kompiler ada untuk membantu dengan mengeluh tentang metode yang hilang.

Gorgi Kosev
sumber
15

Seperti kata Ryan, compiler tsc memiliki saklar --declarationyang menghasilkan .d.tsfile dari .tsfile. Juga catat bahwa (cegah bug) TypeScript seharusnya dapat mengkompilasi Javascript, sehingga Anda dapat meneruskan kode javascript yang ada ke kompiler tsc.

CCoder
sumber
1
tampaknya saat ini mengirimkan file * .js ke tsc menghasilkan kesalahan "Kesalahan membaca file" angular-resource.js ": File tidak ditemukan". Jadi, Anda harus secara eksplisit mengganti nama file * .js menjadi * .ts agar dapat menggunakan tsc. Lihat masalah ini untuk detail lebih lanjut - Saya mencoba menggunakan ini di angularjs: typescript.codeplex.com/workitem/26
James Strachan
3
dari apa yang dapat saya katakan, tsc dapat mengkompilasi semua JavaScript yang valid, tetapi jika itu bukan TypeScript yang valid (kompilasi memberikan peringatan) maka flag --declarations tidak menampilkan file .d.ts, jadi kecuali perpustakaan Anda ditulis dalam TypeScript Anda masih perlu secara manual membuat file deklarasi.
agradl
3

Berikut adalah beberapa PowerShell yang membuat file definisi TypeScript tunggal perpustakaan yang mencakup banyak *.jsfile dengan JavaScript modern.

Pertama, ubah semua ekstensi menjadi .ts.

Get-ChildItem | foreach { Rename-Item $_ $_.Name.Replace(".js", ".ts") }

Kedua, gunakan kompiler TypeScript untuk menghasilkan file definisi. Akan ada banyak kesalahan kompiler, tetapi kita bisa mengabaikannya.

Get-ChildItem | foreach { tsc $_.Name  }

Terakhir, gabungkan semua *.d.tsfile menjadi satu index.d.ts, hapus importpernyataan dan hapus defaultdari setiap pernyataan ekspor.

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 $_ }

Ini diakhiri dengan satu index.d.tsfile yang dapat digunakan yang menyertakan banyak definisi.

Shaun Luttin
sumber
2
Langkah kedua, Dapatkan-ChildItem | foreach {tsc --declaration $ _. Name} berhasil (ditambah param --declaration yang hilang)
Guru_07
3

Saat membuat perpustakaan Anda sendiri, Anda dapat membuat *.d.tsfile dengan menggunakan perintah tsc(TypeScript Compiler) seperti: (dengan asumsi Anda sedang membangun perpustakaan Anda ke dist/libfolder)

tsc -d --declarationDir dist/lib --declarationMap --emitDeclarationOnly
  • -d( --declaration): menghasilkan *.d.tsfile
  • --declarationDir dist/lib: Direktori keluaran untuk file deklarasi yang dihasilkan.
  • --declarationMap: Menghasilkan peta sumber untuk setiap file '.d.ts' yang sesuai.
  • --emitDeclarationOnly: Hanya memancarkan file deklarasi '.d.ts'. (tidak ada JS yang dikompilasi)

(lihat dokumen untuk semua opsi kompiler baris perintah)

Atau misalnya di package.json:

"scripts": {
    "build:types": "tsc -d --declarationDir dist/lib --declarationMap --emitDeclarationOnly",
}

lalu jalankan: yarn build:types(atau npm run build:types)

pembuat magik
sumber
Saya masih tidak tahu bagaimana cara menghasilkan d.tsfile dan dapat menggunakan antarmuka. Apakah Anda punya contoh?
Danosaure
Script npm di atas akan menghasilkan *.d.tsfile dan meletakkannya di dist/libfolder. Anda memang membutuhkan tsconfig.jsonfile di root proyek Anda, tetapi itu seharusnya ada agar proyek tetap bekerja.
MagikMaker
Saya tidak dapat menggunakannya, sekali terbuka. Saya memiliki postingan berikut stackoverflow.com/questions/59742688 jika Anda dapat membuatnya berfungsi?
Danosaure
2

Saya akan mencari pemetaan yang ada dari perpustakaan JS pihak ke-3 Anda yang mendukung Script # atau SharpKit. Pengguna kompiler lintas C # ke .js ini akan menghadapi masalah yang Anda hadapi sekarang dan mungkin telah menerbitkan program sumber terbuka untuk memindai lib pihak ke-3 Anda dan mengubahnya menjadi kelas kerangka C #. Jika demikian hack program pemindai untuk menghasilkan TypeScript di tempat C #.

Jika gagal, menerjemahkan antarmuka publik C # untuk lib pihak ke-3 Anda ke definisi TypeScript mungkin lebih mudah daripada melakukan hal yang sama dengan membaca sumber JavaScript.

Minat khusus saya adalah kerangka kerja ExtJS RIA Sencha dan saya tahu ada proyek yang diterbitkan untuk menghasilkan interpretasi C # untuk Script # atau SharpKit

camelCase
sumber
FYI: Saya baru saja membuat file definisi skrip naskah pertama saya untuk Sencha / ExtJS: github.com/andremussche/extjsTypescript/blob/master/jsondocs/…
André
hey Camel Case, saya telah membuat sebuah blog tentang penggunaan ExtJs dengan naskah: blorkfish.wordpress.com/2013/01/28/using-extjs-with-typescript
blorkfish