Typescript: Dukungan mencari modul di bawah node_modules saat mengimpor

Dibuat pada 25 Jul 2014  ·  138Komentar  ·  Sumber: microsoft/TypeScript

Pembaruan 5 November 2015

Fungsionalitas yang diminta di bawah ini saat ini diimplementasikan dalam TypeScript sejak setidaknya 1,8 dengan satu perbedaan utama:

Alih-alih memiliki properti typescript.main dan typescript.definition , hanya ada satu properti typings yang dapat Anda arahkan ke file d.ts atau .ts normal

Jika Anda mengembangkan modul untuk hanya digunakan secara lokal, Anda dapat mengarahkan typings ke file .ts , tetapi jika Anda berencana untuk menerbitkan modul, disarankan untuk mengarahkannya ke berkas d.ts . Ini karena Anda tidak ingin konsumen modul Anda mengkompilasi ulang file modul Anda, cukup gunakan pengetikannya.

Saya telah menyiapkan contoh penggunaan ini di sini:
https://github.com/chanon/typescript_module_example

Ada halaman dokumentasi di sini yang memiliki informasi lebih lanjut:
http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html

Terima kasih pengembang TypeScript dan semua kontributor.

Masalah asli / permintaan fitur berikut


Motivasi

Dalam TypeScript, jauh lebih sulit untuk menggunakan kembali modul TypeScript dibandingkan dengan menggunakan kembali modul npm dalam JavaScript.

Akan bermanfaat jika compiler TypeScript cukup pintar untuk mencari di folder node_modules dan file package.json.

Alasannya adalah agar pengembang modul npm yang menggunakan TypeScript dapat mulai menulis dan mendistribusikan modul melalui npm itu sendiri. TypeScript akan dapat mendukung infrastruktur npm dan dukungan luas.

Contoh untuk node_modules

Jika kita memiliki:

./node_modules/concator/index.ts
./myApp.ts

Dan di index.ts kami memiliki:

export function concat(param1: string, param2:string): string {
      return param1 + ' ' + param2;
}

di myApp.ts:

import concator = require('concator');  // loads the module from node_modules
var result = concator.concat('I like', 'this.');
var wontWork = concator.concat('this will fail');  // compile error, concat needs 2 params

Jadi pada dasarnya, compiler cukup pintar untuk menemukan modul di node_modules dan secara otomatis menggunakan versi TypeScript (index.ts).

Kemudian ketika kode dikompilasi ke JavaScript, secara alami menggunakan versi JavaScript.

Mengimpor Folder sebagai Modul

Kasus yang lebih mendasar adalah mendukung aturan populer Node.js tentang http://nodejs.org/api/modules.html#modules_folders_as_modules seperti yang disarankan oleh @vvakame di bawah ini dan dalam edisi tertutup (semi-duplikat) #207.

TypeScript.main di package.json

Mungkin ada tambahan file package.json untuk menentukan di mana file .ts utama dari modul npm TypeScript berada. Ini akan mirip dengan kunci main yang menentukan di mana file JavaScript / .js utama berada tetapi untuk TypeScript sebagai gantinya.

Misalnya package.json untuk modul npm bernama "myModule" yang terletak di node_modules/myModule/package.json

{
     "main": "./dist/index.js",
     "typescript": {
          "main": "./src/index.ts"
     }
}

Dalam contoh ini node_modules/myModule/src/index.ts akan menjadi file TypeScript utama dan melakukan import myModule = require("myModule"); akan mengimpor file node_modules/myModule/src/index.ts .

Untuk pembuat kode JavaScript yang menulis var myModule = require("myModule"); dalam file JavaScript, persyaratannya akan memuat file node_modules/myModule/dist/index.js seperti biasa.

Seperti yang dapat dilihat dalam contoh ini, TypeScript src ada di folder node_modules/module-name/src dan file JS yang dikompilasi akan berada di node_modules/module-name/dist .

Sesuatu seperti ini bisa menjadi standar (semi) untuk modul npm TypeScript sehingga sumber TypeScript dipisahkan dengan bersih dari output JavaScript yang dikompilasi.

Kasus yang lebih mendasar seperti yang disarankan oleh @vvakame di bawah ini mendukung aturan Node.js yang populer dari http://nodejs.org/api/modules.html#modules_folders_as_module

TypeScript.definition di package.json

Kunci lain yang mungkin untuk package.json untuk modul npm non-TypeScript (JavaScript biasa) bisa berupa typescript.definition . Ini akan menunjuk ke file .d.ts yang mendefinisikan modul untuk pengguna TypeScript dari modul npm.

Jadi itu
import $ = require('jquery');
akan secara otomatis membaca file jquery.d.ts yang didefinisikan dalam kunci typescript.definition di package.json jQuery dan membuat $ menjadi tipe yang benar.

Contoh format:

{
     "main": "./dist/index.js",
     "typescript": {
          "definition": "./index.d.ts"
     }
}

(Format ini sudah digunakan oleh tsd seperti yang dijelaskan @Bartvds di bawah.)

Kemudian kami pembuat kode TypeScript hanya perlu mencoba untuk mendapatkan sebanyak mungkin pengelola modul npm non-TypeScript untuk menggabungkan permintaan tarik kami yang memiliki file .d.ts dan kunci package.json typescript.definition kami.

Jika kita berhasil dengan itu, maka hidup pembuat kode TypeScript akan bahagia ... tidak ada lagi pengelolaan terpisah dari file .d.ts PastiTyped. Cukup instal npm dan Anda juga mendapatkan definisi TypeScript! Secara otomatis dan up-to-date dengan versi modul yang diinstal.

Daftar Manfaat

Apa yang kita dapatkan dari semua ini adalah

  • modul npm dapat ditulis dalam TypeScript.
  • Baik pembuat kode TypeScript dan JavaScript dapat menggunakan modul ini
  • Pengguna modul yang menggunakan TypeScript mendapatkan manfaat dari pengetikan statis tanpa pembuat kode modul (atau pengguna) harus menggunakan metode biasa untuk menulis (atau menghasilkan) file .d.ts terpisah (jadi ketika kode sumber modul sudah ada di TypeScript kita tidak perlu memiliki file .d.ts lain untuk dipelihara)
  • Akan ada cara untuk dengan mudah menggunakan kembali dan mendistribusikan modul TypeScript menggunakan npm yang sudah dikenal semua orang
  • Ini dapat membantu mempromosikan penggunaan TypeScript itu sendiri, karena pembuat kode JavaScript yang menggunakan modul npm yang ditulis dalam TypeScript mungkin melihat betapa bagus/lebih baik sumber TypeScript dan mencoba beralih ke sana. Atau mereka mungkin ingin berkontribusi pada modul dan karena sumbernya ada di TypeScript, mereka harus mempelajarinya yang dapat membuat mereka menyukainya dan memutuskan untuk menggunakannya dalam proyek mereka sendiri.
  • Pada dasarnya ini akan membantu menumbuhkan komunitas TypeScript melalui semua pembagian kode yang dapat dihasilkan. Saat ini kode TypeScript setiap orang sebagian besar adalah milik mereka sendiri / dalam silo mereka sendiri. Ini sebenarnya mungkin merupakan hal yang sangat penting karena tidak memiliki cara yang tepat/mudah untuk berbagi/mendistribusikan/menggunakan kembali modul mungkin membatasi pertumbuhan bahasa. [1]
  • Penggunaan kembali modul dalam proyek internal akan jauh lebih tidak merepotkan dan akan mengurangi kebutuhan untuk semua jalur relatif ke file .d.ts dan jalur relatif dalam kebutuhan modul, dan hal-hal .d.ts umum. (Saat ini ketika menulis kode TypeScript, saya menemukan saya harus belajar untuk menjadi baik dengan menghitung ../../ s)
  • Pendekatan ini juga mendukung Browserify/Webpack karena Browserify/Webpack juga terlihat di bawah node_modules, jadi ini memungkinkan modul TypeScript terdistribusi yang mudah digunakan kembali / npm untuk server dan browser
  • Modul npm non-TypeScript dapat dengan mudah digunakan dalam TypeScript dengan informasi jenis melalui penambahan kunci typescript.definition . Hal ini memungkinkan file definisi .d.ts untuk dikemas bersama dengan modul npm sehingga memperbarui modul npm akan secara otomatis memperbarui file definisi .d.ts. Ini menghilangkan kebutuhan untuk memperbarui file .d.ts secara manual.
  • Menggunakan file definisi melalui typescript.definition lebih sederhana karena ini hanyalah pernyataan import moduleName = require("moduleName") tanpa perlu ///<reference ... terpisah
  • Menggunakan file definisi melalui typescript.definition juga harus memungkinkan penggunaan versi modul yang berbeda dalam basis kode yang sama tanpa bentrok nama tipe.

Proposal terperinci

@Nemo157 telah menulis proposal yang sangat rinci tentang bagaimana semua ini harus bekerja di:

TypeScript yang Diusulkan Membutuhkan Semantik Resolusi
https://Gist.github.com/Nemo157/f20064a282ee620f3877

Tambahan dalam proposal adalah penggunaan folder /typings yang dapat menyimpan file definisi yang dapat dikelola secara otomatis oleh alat seperti tsd untuk modul JavaScript npm yang tidak menyertakan file definisi dalam repositorinya .

Fakta Pendukung Akhir

Karena TypeScript dikompilasi ke JavaScript yang berjalan terutama di dua tempat: node.js dan di browser, mendukung node_modules bermanfaat untuk kedua tempat (hampir semua tempat TypeScript digunakan) karena npm dan Browserify/Webpack.

yaitu. tidak ada alasan untuk membuat skema yang berbeda ketika node_modules sudah digunakan oleh semua pengguna TypeScript untuk mungkin 75% -100% dari semua kode JavaScript mereka. (Mengambil 25% untuk mungkin pengguna RequireJS.)

Catatan kaki

[1] - BTW saya melihat ada manajer paket NuGet (?) dari Microsoft yang dapat mendistribusikan modul TypeScript (?), tetapi berasal dari latar belakang yang berfokus pada node.js (tidak fokus .NET), saya tidak melihat NuGet menjadi banyak digunakan di luar toko yang berfokus pada Microsoft, terutama karena npm adalah standar _the_ untuk node.js dan juga merupakan standar terkemuka untuk JavaScript sisi klien. Jika saya tidak menggunakan TypeScript, saya tidak akan pernah mendengar tentang NuGet. Rata-rata pembuat kode JavaScript node.js / sisi klien mungkin lebih suka menggunakan npm, alat yang sama yang sudah mereka gunakan daripada harus menggunakan sesuatu yang spesifik Microsoft seperti NuGet. (Saya sebenarnya tidak tahu apa-apa tentang NuGet jadi apa yang saya katakan di sini mungkin tidak terlalu penting.)

Committed Suggestion

Komentar yang paling membantu

Bagaimanapun, kompiler saat ini mengklaim bahwa ia tidak dapat menemukan modul, padahal sebenarnya itu hanya menolak untuk mengimpor modul tanpa definisi tipe. Itu tidak terlalu membantu, bukan?

Semua 138 komentar

[pindah ke TypeScript.main di package.json dalam deskripsi masalah di atas]

:+1:
Saya pikir http://nodejs.org/api/modules.html#modules_folders_as_modules adalah aturan Node.js yang sangat populer.

contoh lainnya.

./test/index.ts

export function hello() { return "Hello, world"; }

./main.ts

import test = require("./test/");
console.log(test.hello()); // print "Hello, world"

[pindah ke TypeScript.definition di package.json dalam deskripsi masalah di atas]

Salah satu solusinya adalah menyelesaikannya dengan perkakas yang lebih baik. Misalnya import foo = require('foo') memberi Anda petunjuk untuk mencari beberapa node_module+package.json lokal (foo adalah proyek ts) atau definisi DT (foo adalah proyek js di mana penulis perpustakaan tidak ingin mempertahankan ts def) .

untuk diketahui; Saya sebenarnya sedang menguji sesuatu yang mirip dengan ini di TSD; cara untuk mengekspos & menautkan definisi yang dibundel dalam paket npm (atau bower).

Itu dalam versi dev saya untuk 0.6, dan berfungsi dengan menambahkan elemen typescript ke package.json (atau bower.json), dengan sub elemen definition (sub elemen karena mungkin satu hari akan ada source juga, atau apa pun).

{
    ...
    "main": "./index.js",
    "typescript": {
        "definition": "./foo.d.ts"
    }
    ...
},

Kemudian Anda dapat menjalankan perintah di TSD, saat ini tsd link dan itu akan memindai semua file package.json di node_modules (atau bower atau apa pun), temukan properti itu jika ditentukan dan tambahkan referensi ke tsd.d.ts pusat

Contoh: didefinisikan di sini dan digunakan di sini

@Bartvds Itu cukup bagus. Bisa menjadi langkah pertama untuk memiliki .d.ts dalam paket npm. Saya suka struktur package.json dengan "definition" di "typescript", itu jauh lebih terorganisir.

Jika kompiler TypeScript sendiri bisa membacanya secara otomatis, akan sangat keren.

Menandai ini untuk diskusi -- resolusi modul eksternal yang lebih cerdas adalah sesuatu yang perlu kita bicarakan untuk memahami berbagai skenario di sini. Ini telah dibahas sebelumnya dan kami membuat beberapa penyesuaian di 1.0.

Juga diskusikan #207 - cari di bawah 'indeks'

:+1:

@chanon tsMain tidak diperlukan jika kita menggunakan pembuatan deklarasi.

Yap, masalah ini sangat penting bahkan untuk browser - banyak proyek menggunakan browserify/packify dan oleh karena itu tata letak direktori yang kompatibel dengan node

:+1:

Sudah ada beberapa pekerjaan di area ini di repo codeplex, satu permintaan tarik oleh leebyron dan satu oleh kayahr .

Saya bermaksud mencoba dan mem-port salah satunya ke repositori baru, tetapi tampaknya kode terkait telah banyak diatur ulang.

Saya telah menulis proposal tentang cara menambahkan ini ke kompiler TypeScript . Ini juga termasuk mencari di direktori typings karena itu akan menjadi penting ketika bekerja dengan modul javascript yang tidak akan mempertahankan definisi Typescript mereka sendiri. Sayangnya untuk membuat ini semua bekerja secara transparan dengan tsd masih akan membutuhkan sedikit pekerjaan karena persyaratan file /// <reference d menjadi deklarasi eksternal ambient membuat segalanya sedikit berbulu. Saya akan melihat penerapan ini di cabang dan memberikan beberapa contoh modul menggunakannya.

Terlihat masuk akal. Apakah ini akan mencakup modul dengan dependensi tipe bentrok? Maksud saya jika aplikasi mengimpor A dan B, dan B juga bergantung pada A. Sangat mudah untuk jatuh ke dalam kesalahan tipe duplikat jika ada dua salinan deklarasi eksternal.

Seharusnya tidak, mereka harus menyelesaikan ke nama modul eksternal yang berbeda jadi nyatakan tipe independen bernama identik dalam modul yang berbeda. Pemeriksaan tipe struktural kemudian harus memungkinkan modul yang berbeda untuk berinteraksi tanpa masalah.

Itulah salah satu masalah utama dengan definisi tsd saat ini yang coba diselesaikan, dengan mendefinisikan modul ambient eksternal, tidak ada cara bagi mereka untuk menangani memiliki beberapa versi perpustakaan dengan nama yang identik, tetapi tipe yang sedikit berbeda .

@joewood juga akan ada masalah antara berbagai versi A

├── [email protected]
└── [email protected]
    └── [email protected]

tidak ada cara bagi mereka untuk menangani memiliki beberapa versi perpustakaan dengan nama yang identik, tetapi tipe yang sedikit berbeda.

tertarik untuk mendengar solusi yang sama. TypeScript memiliki lingkup variabel level global untuk deklarasi ambient

Bahkan jika versinya cocok, saat ini saya melihat masalah dengan dua file deklarasi ambient yang berbeda, tetapi menyebabkan kesalahan simbol duplikat. Direktif /// reference yang ditentukan secara lokal perlu entah bagaimana menyelesaikan kembali ke satu file. Entah itu, atau identitas tipe perlu menyertakan jalur dan pengetikan struktural akan menangani ketidakcocokan versi, dll.

@joewood Ya, itulah yang saya harap akan diperbaiki di sebagian besar kasus dengan mengubah require untuk memuat definisi yang benar, menghindari /// reference sedapat mungkin. Modul eksternal akan diidentifikasi oleh jalur absolutnya alih-alih memiliki deklarasi ambient, jadi memuat beberapa nama yang sama dari jalur yang berbeda dan pada versi yang berbeda harus dimungkinkan.

Ya, itulah yang saya harap akan diperbaiki di sebagian besar kasus dengan mengubah persyaratan untuk memuat definisi yang benar, menghindari referensi /// sedapat mungkin.

:+1:

:+1: Terima kasih @Nemo157 dan semuanya untuk diskusinya.

Saya telah memperbarui teks masalah teratas untuk menggabungkan penambahan package.json dan menautkan ke proposal @Nemo157 .

:+1:

Saya telah melakukan implementasi awal proposal saya bersama dengan membuat kumpulan contoh modul untuk menunjukkan bahwa semua cara berbeda untuk membuat modul akan berhasil. Termasuk menggunakan versi berbeda dari pustaka yang sama di sub-modul yang berbeda.

:+1:

Folder sebagai modul dengan index.ts :+1:

:+1:

:+1:

:+1:

:+1:

:+1: :+1: :+1:

:+1: :+1: :+1: :+1:

Mengomentari untuk mengembalikan ini ke radar kami.

Saya telah sukses dengan saran @Bartvds :

Kemudian Anda dapat menjalankan perintah di TSD, saat ini tautan tsd dan itu akan memindai semua file package.json di node_modules (atau bower atau apa pun), temukan properti itu jika ditentukan dan tambahkan referensi ke bundel tsd.d.ts pusat dalam proyek Anda.

Jadi pertimbangkan untuk mendukung typescript di package.json karena begitulah cara komunitas berjalan.

Kita pasti membutuhkan tsc untuk mengetahui folder node_modules jika TypeScript akan digunakan secara luas di komunitas node.js. Saat ini saya menggunakan symlink ke modul yang merupakan bagian dari proyek pengembangan saya (menggunakan npm-workspace), dan saya memiliki dua opsi saat ini:

  • impor langsung dari node_modules, yang terlihat salah: import Foo = require("node_modules/mymodule/Foo");
  • dapatkan tsc untuk menghasilkan file deklarasi dan kemudian gabungkan mereka menggunakan file deklarasi modul yang dikelola secara manual yang mengganti nama modul string

Bisakah tsc memeriksa nama modul eksternal dalam deklarasi impor dan kemudian selama resolusi jalur juga menerapkan node_modules dengan cara yang sama seperti runtime node.js? Opsi kompiler juga dapat mengaktifkan atau menonaktifkan ini.

:+1: :+1: :+1:

Bisakah tsc memeriksa nama modul eksternal dalam deklarasi impor dan kemudian selama resolusi jalur juga menerapkan node_modules dengan cara yang sama seperti runtime node.js

Beginilah _seharusnya_. Cara saat ini hanya mencari pohon direktori untuk menemukan file dengan nama tersebut tidak memiliki kemiripan dengan konteks eksekusi JS.

Ini telah ada di daftar saya untuk sementara waktu sekarang. akan mencoba untuk mendapatkan ini di rilis berikutnya.

Kami ( Booktrack ) menggunakan TypeScript untuk semua pengembangan web kami, dan kami menghadapi tantangan serupa dengan pengembang node.js. Saya angkat bicara karena suara pengembang web tidak sekeras suara pengembang node.

Solusi (dalam urutan yang terburuk untuk kami hingga yang terbaik untuk kami):

  1. resolusi nama modul eksternal tingkat atas melalui pencarian kode keras ke node_modules
  2. tidak ada kontrol atas resolusi nama modul eksternal tingkat atas
  3. flag compiler untuk mengontrol resolusi opsional dari nama modul eksternal tingkat atas ke dalam direktori node_modules
  4. parameter "jalur pencarian modul" kompiler untuk mengontrol resolusi opsional dari nama modul eksternal tingkat atas ke dalam jalur yang diberikan
  5. parameter "penyelesai modul" kompiler untuk menyediakan kompiler dengan plugin JS yang akan menyelesaikan semua (bukan hanya tingkat atas) nama modul eksternal
  6. kait yang sesuai ke layanan bahasa sehingga resolusi nama modul eksternal dapat dikontrol

Opsi 1 mengerikan, saya lebih suka opsi 2.

Opsi 5 dan 6 akan memungkinkan penggunaan pernyataan impor yang eksotis, seperti yang ditemukan saat bekerja dengan plugin requirejs atau webpack. Ide dasarnya: kompiler mendelegasikan semua pencarian nama modul eksternal (bukan hanya tingkat atas) ke pihak ketiga (plugin atau panggilan balik). Delegasi, yang diberikan jalur ke modul di bawah kompilasi dan nama modul eksternal, mengembalikan ke kompiler jalur sistem file ATAU informasi tipe untuk nama modul yang diberikan.

Saya akan senang jika opsi 4 diimplementasikan, senang jika opsi 6 diterapkan dan over-the-moon jika opsi 4 dan opsi 6 diterapkan.

Bagaimana dengan --basePath untuk root pencarian modul Anda, semua impor modul akan terlihat relatif terhadap jalur itu. Ini hanya berlaku untuk AMD.

Saya pikir masalah simpul jauh lebih sederhana, kita hanya perlu menerapkannya :)

Perhatikan bahwa kami benar-benar mendapatkan implementasi (dan pengujian) dari @Nemo157 di sini sejak lama https://github.com/Microsoft/TypeScript/issues/247#issuecomment -57422329

Setuju dengan @mark-buer dan @mhegazy , opsi 4 jalur pencarian harus menjadi perbaikan sederhana. Solusi yang lebih rumit dalam layanan bahasa (opsi 6) jelas diperlukan dalam jangka waktu yang lebih lama.

_Layak menambahkan_: ini saja tidak akan memperbaiki masalah penggunaan kembali TypeScript di npm karena masalah simbol duplikat untuk referensi tipe umum #1125. Kita benar-benar harus menghindari ///dengan menggunakan file .tsconfig dan perbaiki ini dengan benar dengan menggabungkan paket ke dalam satu modul yang diketik eksternal seperti yang disarankan di #17

Suara lain untuk membuat folder node_modules dikenali oleh kompiler TypeScript.

Untuk modul CommonJS, TypeScript idealnya harus mengikuti resolusi nama file yang sama seperti yang dibutuhkan.resolve (seperti yang dijelaskan oleh psuedocode di halaman ini: http://nodejs.org/api/modules.html#modules_all_together.

fungsi ini sangat penting untuk memungkinkan integrasi kompiler TypeScript ke dalam pemaket node lain, seperti browserify. Tambalan @Nemo157 berfungsi dengan baik, tetapi tidak memungkinkan pengujian yang mudah dengan pembuat paket yang ada karena sebagian besar telah pindah ke versi TypeScript yang lebih baru dan tidak lagi kompatibel dengan kodenya

Di mana direktori node_modules harus relatif terhadap sumber?

Atom-TypeScript sekarang mendukung typescript.definition di luar kotak. Detail: https://github.com/Microsoft/TypeScript/issues/2829

Anda juga dapat membuat paket seperti itu dengan mudah menggunakan atom-typescript :rose: lagi lihat #2829

Keterbatasan

Ini akan bekerja _flawlessly_ jika Anda berbagi paket yang tidak bergantung pada perpustakaan eksternal mana pun. Jika ya maka kita membutuhkan algoritma resolusi konflik modul.

Saya terbuka untuk saran untuk kasus ini, tetapi rencana saya adalah:

  • kami melakukan beberapa hal cerdas dalam membaca d.ts seperti itu tidak memberi TypeScript komentar eksternal reference (misalnya node.d.ts di sini https://github.com/TypeStrong/atom-typescript-examples /blob/master/node/node_modules/example-typescript-b/definition/sample-bdts) Dan alih-alih menunjuk ke .d.ts kita sendiri jika kita memilikinya di Pengetikan kita.

Apakah ini akan tetap di jalur untuk 2.0? Sepertinya semacam fitur penting untuk adopsi Node.js, yang saat ini menyakitkan, bahkan dengan PastiTyped dan sejenisnya.

Sepertinya semacam fitur penting untuk adopsi Node.js, yang saat ini menyakitkan, bahkan dengan PastiTyped dan sejenisnya.

@LPGhatguy Silakan lihat https://github.com/Microsoft/TypeScript/issues/2338. @vladima sedang mengerjakannya tetapi belum menganggapnya sebagai tonggak sejarah :rose:

@LPGhatguy kami mencoba untuk mendapatkan ini di rilis berikutnya. semoga secepatnya.

@mhegazy Maksudmu 1.6? Itu akan luar biasa!

Apakah itu terkait dengan #2338?

ya untuk TypeScript 1.6 (setidaknya ini yang kami coba lakukan), ya untuk #2338; ada beberapa perubahan dan masalah lain di sekitar ini termasuk #3147 dan #4154

Lalu, mengapa itu ditandai sebagai TypeScript 2.0 sebagai tonggak sejarah?

terima kasih @heycalmdown , menghapus tonggak sejarah. kami biasanya tidak menandai pencapaian pada saran. mudah-mudahan kami memiliki pembaruan dalam waktu seminggu atau lebih tentang masalah ini. tetap disini.

Saya ingin berpadu untuk meminta dukungan modul ES6 untuk mengikuti ini juga (yang menurut saya akan?)

Mengetik untuk

import mylib = require('mylib');
mylib.foo(mylib.bar);

harus berperilaku sama dengan

import { foo, bar } from 'mylib';
foo(bar);

Saya ingin berpadu meminta dukungan modul ES6 untuk mengikuti ini juga (yang menurut saya akan?

@DavidSouther Itu akan _otomatis_ menjadi kasusnya. Pencarian antara keduanya konsisten :rose:

ini ditangani oleh #4154.

Jika saya menggunakan nightly, mulai besok saya harus mengimpor modul node ke "hanya berfungsi"?

Pertanyaan:
Saya pikir itu adalah konvensi umum untuk memiliki file bernama
"indeks" di commonJS dan
"utama" dalam AMD
untuk jalur pendek.
Dalam pertanyaan di atas, penulis mengimpor
/node_modules/concator/index.ts sebagai
import concator = require('concator');

Maafkan saya - Saya sedang mencari tahu apakah resolusi indeks juga didukung sekarang dan bagaimana dengan index.ts atau main.ts di AMD memerlukan resolusi?
Saya juga melakukan ping ke @basarat untuk mengetahui apakah itu / akan didukung oleh https://github.com/TypeStrong/atom-typescript karena sekarang tidak memungkinkan saya untuk memerlukan index.ts seperti yang disebutkan di atas.

@sebilasse , jika Anda menggunakan typescript@next hari ini, ini akan bekerja dengan --module commonjs

import concator = require('concator'); // resolves to node_modules/concator/index.ts

Tidak ada perubahan cara resolusi AMD dari rilis sebelumnya.

@DavidSouther seharusnya di typescript@next hari ini. cobalah dan beri tahu kami bagaimana tarifnya.

@mhegazy @basarat :+1: oke. Tetapi bagaimana pendapat Anda tentang resolusi AMD untuk main.ts atau index.ts - bukankah seharusnya konsisten di masa mendatang?

@sebilasse , untuk AMD saya pikir kita perlu melakukan sesuatu seperti yang dicatat oleh @vladima di #2338 (bagian untuk: pemuat modul RequireJS/ES6).

Sangat bagus!! \Hai/

@mhegazy Masih tidak berfungsi seperti yang saya harapkan.

Saya mengumpulkan https://github.com/DavidSouther/typescript-example-using-node dengan use case "ideal" saya. tslib adalah pustaka sederhana yang mengekspor satu fungsi. tsclient bergantung pada tslib, serta readline dari paket Node. Skrip pengaturan adalah kemudahan untuk menginstal, menautkan, dan mengeksekusi. Saya telah menyertakan run, dan membubuhi keterangan bagian yang tidak terduga dengan komentar sebaris.

% ./setup
...
> [email protected] build ~/ts-node/tslib
> tsc --version ; tsc -p src/

message TS6029: Version 1.7.0-dev.20150831
...
> [email protected] build /Users/southerd/devel/tmp/ts-node/tsclient
> tsc --version ; tsc -p src/

message TS6029: Version 1.7.0-dev.20150831
# Expect this to find tslib, but fail type checking.
# See tsclient/app.ts for details
src/app.ts(4,21): error TS2307: Cannot find module 'tslib'.

+ node ./dist/app.js # This works as expected!
What would you ask? What is the meaning of life?
42
+ set +x

Saya juga tidak mendapatkan dukungan bahasa untuk impor tslib di tsclient (VSCode Versi 0.7.0 (0.7.0), meskipun saya tidak sepenuhnya yakin TSC mana yang digunakan, atau bagaimana mengubahnya.

@DavidSouther TypeScript compiler memeriksa bidang 'mengetik' di package.json untuk menemukan file '.d.ts'. Dengan perubahan ini saya mendapatkan src/app.ts(13,7): error TS2322: Type 'string' is not assignable to type 'number'. yang terlihat seperti kesalahan yang sah

Ah, saya pasti melewatkan dokumen itu. Saya masih mengalami masalah kedua - bagaimana cara mengubah versi VSCode tsc?

Anda dapat memberikan lokasi TypeScript SDK khusus ke VSCode melalui pengaturan "typescript.tsdk" - itu harus menunjuk ke folder yang berisi tsserver.js dan file '.d.ts' standar. Jika TypeScript diinstal sebagai paket npm, itu akan menjadi seperti

// Place your settings in this file to overwrite the default settings
{   
    "typescript.tsdk": "C:\\Sources\\bugs\\node\\typescript-example-using-node\\tslib\\node_modules\\typescript\\lib"       
}

Apakah ada yang mendapatkan sampel bekerja? Saya mencoba sepanjang sore untuk bermain dengan ini, tetapi saya selalu berakhir dengan

error TS2307: Cannot find module

Saat ini kodenya ada di node_modules/my-module/. Dan saya mendefinisikan index.ts yang menangani ekspor semuanya, dan saya mereferensikannya di package.json di bawah TypeScript.main. Dalam proyek konsumen saya mencoba import {AClass} dari 'my-module'; dan import my-module = require('my-module'); Keduanya menyebabkan kesalahan yang sama dengan TypeScript 1.7.0-dev.20150901.

Saat menyelesaikan modul dengan nama non-relatif, dengan --module commonjs , kompiler akan mencari .d.ts yang cocok dengan nama di node_modules\name\index.d.ts atau mencari di package.json untuk properti typings , dan memuat .d.ts yang ditunjuknya.

dari deskripsi Anda, sepertinya Anda mengaturnya ke index.ts , Anda tidak benar-benar ingin mengkompilasi dependensi Anda, Anda hanya ingin menggunakan pengetikan mereka, jadi Anda harus mengaturnya ke index.d.ts sebagai gantinya.

Saya telah memperbarui langkah-langkah dalam algoritma resolusi modul node untuk mencerminkan implementasi: https://github.com/Microsoft/TypeScript/issues/2338

@DavidSouther Saya memiliki masalah yang sama persis rupanya. Ketika saya mengkompilasi dengan ketergantungan pada node_modules itu tidak dapat menyelesaikan modul dan menghasilkan kesalahan, tetapi kemudian, itu masih menghasilkan js, dan jika saya menjalankannya, itu berjalan. Mungkin karena pengaturan saya, saya tidak tahu. D.ts saya sebagian besar kosong, saya memiliki index.ts yang menangani impor dan ekspor ulang semua kelas modul saya yang ditentukan dalam banyak file .ts. Dan kemudian file d.ts saya hanya mereferensikan index.ts ini dan mengekspor semuanya dari index.ts seperti ini:

/// <reference path="index.ts" />

declare module 'my_module' {
    export * from 'index';
}

Juga, entah bagaimana masih mengkompilasi ts dari node_modules, oleh karena itu saya harus menambahkan tugas bersih untuk menghapusnya setelah kompilasi. Apakah ada deskripsi fitur di suatu tempat yang meringkas proses?

edit: Saya membuatnya berfungsi, tetapi ini sangat meretas dan masih menghasilkan kesalahan. Saya membuat d.ts dengan dts-generator, dan kemudian saya mengimpor kelas saya seperti ini:

import MyClass from '../../node_modules/my_module/dist/MyClass';

Jika saya menggunakan import MyClass from 'my_module/MyClass' saya mendapatkannya untuk dikompilasi tanpa kesalahan, tetapi saat runtime saya mendapatkan kesalahan tidak dapat menemukan modul 'my_module/MyClass'. Dengan solusi di atas, ini menunjuk langsung ke .js yang dikompilasi dan pada saat runtime entah bagaimana berfungsi, meskipun itu menghasilkan kesalahan tidak dapat menemukan modul pada waktu kompilasi.

Masih mengalami masalah saat mengimpor dari submodul (mis. npm install angular2, import { Inject, Binding } from 'angular2/di' . Akan bekerja untuk mendapatkan test case yang ada malam ini.

Jangan berpikir bahwa angular sudah menggabungkan pengetikan seperti yang diharapkan oleh kompiler TypeScript.

Itu mungkin benar; Saya akan bekerja dengan mereka dan melihat di mana itu berakhir.

fitur ini bekerja dengan baik pada TypeScript 1.1, misalnya https://github.com/Nemo157/typescript_w_node_modules_example

tapi gagal di TypeScript 1.5.3, ada yang berubah?

------ memperbarui ---------

Saya tahu itu akan dirilis dalam 1.6, terima kasih

Saya hanya bisa mendapatkan "setengah bekerja" ini di 1.6.2

Pertama, saya mengemas perpustakaan dengan my-lib.d.ts di direktori dist , dan menunjuk ke file ini di atribut package.json file typings (misalnya "typings" : "dist/my-lib.d.ts" )

Kemudian saya mengimpor perpustakaan ini dalam file TypeScript Test.ts menggunakan

import { MyObject } from "my-lib"

MyObject diimpor dengan benar dan kode js dipancarkan pada transpilasi.
Visual Studio Code bahkan memberikan penyelesaian pada MyObject

Namun saya mendapatkan peringatan kompiler bahwa:
Test.ts(10,60): error TS2306: File '[]/node_modules/my-lib/dist/my-lib.d.ts' is not a module.

Visual Studio Code sebenarnya akan menunjukkan impor sebagai kesalahan keras

Setiap modul yang diimpor dari paket node harus berupa "modul eksternal" dan bukan "deklarasi modul ambient". yaitu tidak ada deklarasi declare module "foo" {.. } , melainkan deklarasi impor atau ekspor tingkat atas dalam file.

Jadi jika paket Anda "my-lib" ditulis dalam TypeScript, buat saja dengan --declarations dan atur pengetikannya ke file .d.ts dari modul utama Anda. jika tidak, dan pengetikan Anda adalah sesuatu yang Anda tulis sendiri, atau dapatkan dari yang pasti diketik, maka Anda perlu mengubahnya ke modul eksternal, atau menunggu hingga #4665 diselesaikan (semoga segera).

Alasan pembatasan ini adalah ini dapat menyebabkan polusi lingkup global dan konflik di kemudian hari bagi pengguna paket Anda. ada diskusi panjang tentang ini di #4665.

Berikut adalah beberapa dokumentasi untuk pencarian di masa mendatang: https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages

@mhegazy Terima kasih atas balasan cepat Anda yang sangat membantu dalam pencarian saya untuk mengotomatisasi pembuatan perpustakaan commonjs, yang ditulis dalam TypeScript, yang dapat digunakan oleh kode Javascript dan TypeScript.
Sintaks dan resolusi import/export telah bergerak sangat cepat baru-baru ini sehingga apa yang saya kira hilang saat ini adalah panduan definitif tentang cara membuatnya.

Saya membuatnya bekerja ... dengan satu peringatan (dan karenanya pertanyaan lain)

Berikut adalah tampilan setup yang disederhanakan.

Pustaka terdiri dari tiga objek A1, A2 dan B dalam 2 file TypeScript A.ts dan B.ts; sesuatu seperti

sumber

A.ts

class A1{}
class A2{}
export { A1, A2 }

B.ts

class B{}
export { B }

Apa yang ingin kami ekspos dikumpulkan dalam index.ts :

export * from './A'
export * from './B'

membangun
Pembuatan dilakukan dengan bantuan grunt dan flag --module commonjs dan --declaration disetel pada tsc 1.6.2
Hasil akhir dari build adalah pohon yang terlihat seperti

    package.json
    dist/
        js/
             A.js
             B.js
             index.js
        typings/
             A.d.ts
             B.d.ts
             index.d.ts

package.json berisi dua entri ini:

"main": "dist/js/index.js",
"typings": "dist/typings/index.d.ts"

Menggunakan perpustakaan ini di TypeScript 1.6.2 dengan import {A1, A2, B} from "mylib" sederhana berfungsi dengan baik. Ketergantungan beberapa tingkat (yaitu perpustakaan yang saling mengimpor) juga berfungsi dengan baik.

Di mana masalah muncul adalah ketika perpustakaan bergantung pada perpustakaan lain yang _bukan_ perpustakaan TypeScript.
Katakanlah perpustakaan bergantung pada Node.js.
Di salah satu file sumber akan ada referensi ke pengetikan NodeJS misalnya
///<reference path="../typings/node/node.d.ts"/>

Setelah transpilasi instruksi <reference > akan berakhir di file deklarasi yang sesuai; masalahnya adalah jalur ke node.d.ts kemungkinan salah atau tidak ada.
Apakah ada cara yang disarankan untuk melakukan ini?

_Note_: masalah ini diatasi dengan penggunaan pada file index.ts untuk mengekspos bagian menarik dari perpustakaan, karena index.ts tidak memiliki alasan untuk memuat instruksi <reference > dan dengan 1.6 .2, kompiler tampaknya tidak peduli bahwa Adts memiliki jalur yang tidak valid dalam instruksi referensi

@bgrieder Kami menangani ini di Fosfor menggunakan tsconfig.json :
https://github.com/phosphorjs/phosphor-widget/blob/master/src/tsconfig.json

Kami hanya menambahkan pengetikan eksternal yang kami butuhkan ke file yang dikompilasi. Ini berarti bahwa jika salah satu dari tipe eksternal tersebut adalah bagian dari antarmuka publik kami, konsumen kode juga perlu menyediakan pengetikan eksternal tersebut sebagai bagian dari build mereka. _Ini tidak apa-apa_. Jika kita menggabungkan definisi tersebut, dan beberapa lib lain yang digunakan oleh konsumen _juga_ menggabungkan definisi yang sama, akan ada konflik simbol duplikat.

@sccolbert Ya!
Saya khawatir menghapus instruksi <reference ...> akan merusak pelengkapan otomatis pada semua IDE, tapi hei, tidak: setidaknya Visual Studio Code 0.8.0 tampaknya cukup pintar untuk memilih definisi tersebut dari tsconfig.json berkas! (setelah restart)

Selesai dengan reference . Bagus sekali !

@sccolbert

Bagaimana jika Anda menggunakan proyek Node.js biasa di dalamnya dan *.d.ts untuknya, bagaimana solusi tsconfig membantu Anda?

@heycalmdown Anda baru saja menambahkan d.ts ke bidang files pada tsconfig , berikut ini contoh yang melakukan itu:

https://github.com/phosphorjs/phosphor-widget/blob/master/test/src/tsconfig.json#L11
https://github.com/phosphorjs/phosphor-widget/blob/master/test/src/index.ts#L10

Perhatikan bahwa kita harus menggunakan require di sini daripada import hanya karena cara file d.ts untuk expect.js ditulis secara internal.

Oke, saya mengerti. Repositori Anda terlihat seperti contoh yang bagus.

Apakah ini benar-benar telah diterapkan di TypeScript 1.6.2?

Jika sudah, dapatkah seseorang memberi tahu saya apa yang saya lakukan salah di sini?:
https://github.com/chanon/typescript_module_example

Anda mungkin menginginkan sintaks impor es6.

Pada Rabu, 4 November 2015, 06:10 chanon [email protected] menulis:

Apakah ini benar-benar telah diterapkan di TypeScript 1.6.2?

Jika ya, dapatkah seseorang memberi tahu saya apa yang saya lakukan salah di sini?:
https://github.com/chanon/typescript_module_example


Balas email ini secara langsung atau lihat di GitHub
https://github.com/Microsoft/TypeScript/issues/247#issuecomment -153688004
.

Saya baru saja memperbaruinya untuk menggunakan sintaks impor es6 dan saya masih mendapatkan kesalahan yang sama (tidak dapat menemukan modul).

@chanon package.json untuk node_modules paket harus memiliki kunci typings yang menunjuk ke file d.ts , _not_ a typescript penunjuk kunci .ts file seperti yang Anda miliki sekarang.

Kami menggunakan resolusi modul node di PhosphorJS secara eksklusif (pada TS 1.6.2) dan berfungsi dengan baik. Berikut ini contohnya: https://github.com/phosphorjs/phosphor-widget/blob/f908341cb1d46ada8ad8149e695a75e7ea2fde57/package.json#L6

Terima kasih @sccolbert , namun proposal awal saya (di bagian atas masalah ini) adalah mengizinkan properti typescript.main di package.json yang akan menunjuk ke titik masuk TypeScript utama untuk paket modul simpul yang ditulis di TypeScript.

Ini akan memungkinkan untuk mengimpor modul TypeScript dalam kode TypeScript tanpa memerlukan file pengetikan d.ts (bahkan tidak perlu membuatnya).

@chanon Saya baru saja menunjukkan apa yang perlu Anda lakukan untuk menjalankan kode Anda.

@sccolbert saya mengerti terima kasih.

Dapatkah seseorang yang mengetahui memberi tahu saya jika saya harus membuat masalah lain yang meminta fitur khusus ini?

Masalah utama terkait dengan logika resolusi modul (selain yang ini) tampaknya #2338 yang ditutup dan #5039 yang tampaknya tentang mendukung resolusi jalur gaya SystemJS yang terlihat sangat kompleks.

Namun hanya mengimpor gaya CommonJS sederhana seperti yang diminta pada awalnya dalam masalah ini tampaknya telah dilupakan? Setidaknya bagian tentang TypeScript.main dan folder sebagai modul?

Saya tidak mengerti perlunya memiliki (dan keinginan untuk memiliki) file d.ts jika modul dan konsumen modul sudah ditulis dalam TypeScript.

Sebenarnya tidak jauh berbeda dengan mengimpor file TypeScript yang relatif ex.

Alih-alih harus melakukan:
import * as lib from '../relative/path/to/typescriptFile.ts'

Atau:
import * as lib from '../../node_modules/myModule/index.ts'

Biarkan TSC dapat menemukan file TypeScript untuk diimpor menggunakan resolusi jalur node_modules normal. Dan setidaknya izinkan untuk mengimpor folder sebagai modul (dengan index.ts) sehingga pada contoh kedua saya dapat melakukan:

import * as lib from 'myModule'

Atau karena "Anda tidak benar-benar ingin mengkompilasi dependensi Anda, Anda hanya ingin menggunakan pengetikan mereka"?

@chanon perilaku yang Anda uraikan adalah apa yang ada di master sekarang. dapatkah Anda mencoba typescript@next ?

implementasi asli #2338 menambahkan beberapa pemeriksaan tambahan untuk memastikan itu adalah .d.ts, dan itu terutama karena alasan yang Anda sebutkan. Anda tidak ingin pengguna paket Anda mengkompilasi "sumber" Anda pada setiap permintaan kompiler, dan mendapatkan keluaran berbeda berdasarkan opsi kompiler mereka, Anda hanya ingin membagikan pengetikan Anda.

Namun jika Anda sedang membangun kedua paket, Anda mungkin ingin melakukannya sambil mengulanginya. Pembatasan telah dihapus di #5278.

Silakan lihat halaman wiki untuk berbagi pengetikan melalui paket npm untuk informasi lebih lanjut: https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages

Terima kasih atas klarifikasi Anda @mhegazy! Saya akan mencobanya.

@mhegazy Baru saja mencoba dengan typescript@next , berfungsi seperti yang diharapkan!

Ini bagus!!

Dan terima kasih semuanya untuk berpartisipasi dalam ini dan masalah terkait :+1:

Saya telah menambahkan pembaruan pada teks masalah di atas untuk menjelaskan cara penerapan fitur ini.

Beresiko melangkah ke ladang ranjau, bagaimana ini diharapkan bekerja dengan modul npm lama yang _tidak_ memiliki properti typings di package.json? Mencoba menggunakan tape atau get-parameter-names dengan typescript@next menyebabkannya meledak di wajah saya karena tidak dapat menemukan paket-paket itu karena mereka tidak memilikinya Properti.

Tentu, itu bukan modul TypeScript, tetapi sepertinya saya tidak dapat menemukan solusi dan itu mengunci sebagian besar ekosistem npm.

@danpantry Biasanya Anda akan menggunakan file .d.ts normal yang ditulis khusus untuk modul itu. Proyek PastiTyped memiliki file .d.ts untuk banyak modul umum. Ada utilitas tsd yang dapat membantu menginstal dan mengelola file .d.ts dari PastiTyped untuk Anda.

Anda dapat menggunakan modul normal tanpa mengetik hanya dengan menggunakan sintaks biasa yang dibutuhkan commonjs.

misalnya
var moduleName = membutuhkan("namamodul")

@chanon terasa seperti peretasan untuk menggunakan sintaks require 'klasik' saat menggunakan sintaks ES6 dengan TypeScript sehingga saya dapat menggunakan dependensi JavaScript, tetapi terima kasih. Saya telah mendengar tentang utilitas tsd tetapi saya tidak yakin bagaimana itu akan menjadi faktor untuk menggunakan impor ES6 .. kecuali saya harus mulai menggunakan /// <reference path=... untuk modul semacam ini?

Ya itu salah satu caranya. Cara lain adalah dengan kami file tsconfig.json dan menempatkan file tsd.d.ts root Anda sebagai file pertama.

Anda mungkin juga tertarik untuk membaca ini, mencakup tsd dan mengetik https://angularclass.com/the-state-of-typescript-packages/

@joewood terima kasih atas infonya, terakhir kali saya melihat ke TypeScript adalah pada hari-hari file .d.ts individual. artikel yang bagus

@chanon @danpantry Agak disayangkan bahwa import foo = require('foo') (dengan foo di bawah node_modules) tidak bekerja ketika foo's package.json tidak memiliki pengetikan.

@wmono baik, karena mungkin TypeScript 0.80 atau mungkin sebelumnya sintaks import foo = require('foo') hanya untuk mengimpor modul dengan pengetikan. Jika tidak memiliki pengetikan, Anda akan menggunakan var foo = require('foo') sebagai gantinya. Jadi saya akan mengatakan itu seperti apa adanya.

@chanon Maafkan saya; kesalahan pengguna. Sepertinya webpack sedang berjuang dengan require "telanjang" tetapi masalahnya ada di tempat lain.

Maaf ada yang bisa jelasin kenapa
var foo = require('foo');
Bekerja untuk node_module standar tanpa mengetik tetapi
import foo from 'foo';
tidak? Apakah itu hanya didefinisikan secara sewenang-wenang? Saya tidak mengerti mengapa yang terakhir _tidak boleh_ berfungsi - Saya tidak peduli apakah perpustakaan JS eksternal memiliki pengetikan atau tidak.

Maaf ada yang bisa jelasin kenapa
var foo = membutuhkan('foo');
Bekerja untuk node_module standar tanpa mengetik tetapi
impor foo dari 'foo';
tidak? Apakah itu hanya didefinisikan secara sewenang-wenang? Saya tidak mengerti mengapa yang terakhir tidak berfungsi - saya tidak peduli apakah perpustakaan JS eksternal memiliki pengetikan atau tidak.

@harangue karena var require adalah salah satu sintaks modul yang bersaing (yang ini commonjs dan yang lainnya dalam daftar termasuk amd ) yang didukung _di luar sistem pemeriksaan tipe_. Jika seseorang ingin menggunakan sistem tipe yang akan dilakukan import require . Dengan ES6 mengambil :hammer: dan mengatakan bahwa satu sintaks (:ring:) untuk mengatur semuanya ... masuk akal untuk memiliki sintaks modul yang didukung oleh sistem pengecekan tipe di luar kotak :rose:

@basarat Terima kasih atas klarifikasinya. Ikon juga membantu. ;) Saya masih tidak yakin mengapa sintaks ES6 mengamanatkan pengecekan tipe. Apa yang menghentikan kompiler untuk mengatakan - "oh, saya tidak dapat menemukan data tipe apa pun untuk modul itu tetapi saya akan tetap mengimpornya". Efek samping apa yang akan ditimbulkan oleh perilaku (agak intuitif, IMO) ini?

Ini membingungkan bagi mereka (seperti saya) yang berasal dari ES6 ke TypeScript. Saya berharap sintaks impor modul ES6 berperilaku dengan cara yang sama di TypeScript, tetapi sayangnya itu tidak berfungsi sama sekali untuk sebagian besar paket npm ...

tapi sayangnya itu tidak berfungsi sama sekali untuk sebagian besar paket npm ...

@teohhanhui saya bingung. Bisakah Anda memberikan contoh konkret tentang apa yang ingin Anda capai dan kode apa yang Anda coba capai. Ini hanya agar saya dapat membantu Anda :rose:

import koa from 'koa';

memberikan Cannot find module 'koa'. (2307) ketika target adalah es6

koa (tentu saja) ada di node_modules

Namun, koa tidak mempublikasikan pengetikan TypeScript dengan proyek mereka. Ini hanya untuk paket yang menerbitkan .d.ts dengan proyek mereka, dan mencantumkannya di package.json mereka. Karena koa tidak, Anda juga ingin menginstal definisi tipe tersebut dari Pasti Diketik.

Itu sepertinya keputusan yang buruk karena orang akan mengharapkan pernyataan import hanya berfungsi seperti pada modul ES6 biasa. (Ya saya tahu, sebagian besar paket npm adalah modul CommonJS tetapi mendukungnya di sini masih merupakan hal yang masuk akal untuk dilakukan.)

Saya baru mengenal TypeScript jadi saya mungkin memiliki pemahaman yang salah, tetapi bukankah definisi tipe opsional? Mengapa saya tidak dapat mengimpor paket tanpa definisi tipe? Saya tidak ingin dipaksa untuk mencari/membuat definisi tipe.

Beralih ke sintaks impor modul TS lama bukanlah opsi karena tidak diizinkan saat menggunakan target es6 .

Saya baru mengenal TypeScript jadi saya mungkin memiliki pemahaman yang salah, tetapi bukankah definisi tipe opsional?

Itu tidak benar. Definisi tipe _dalam kode Anda sendiri_ bisa implisit, yang berarti kompiler TypeScript akan "mencari tahu". Anda tidak akan pernah melewati perpustakaan pihak ketiga melalui kompiler TypeScript, jadi kompiler tidak pernah tahu apa tipe itu. Jika Anda berencana menggunakan kode pihak ketiga, Anda harus benar-benar mempelajari cara menggunakan Pasti Diketik dan alat tsd .

Bagaimana dengan jawaban dari @basarat ini?

http://stackoverflow.com/a/27434010/1529493

Mengapa modul non-TypeScript tanpa definisi tipe tidak dapat diimpor seperti itu?

Mereka dapat: const koa = require(‘koa’)

Pada 21 Jan 2016, pukul 14:47, Teoh Han Hui [email protected] menulis:

Mengapa modul tanpa definisi tipe tidak dapat diimpor seperti itu?


Balas email ini secara langsung atau lihat di GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173574234.

@bgrieder Saya mengacu pada sintaks impor ES6.

(yaitu Anda menggunakan commonjs), jika tidak, gunakan declare var dari jawaban Basarat

Pada 21 Jan 2016, pukul 14:48, Bruno Grieder bruno. [email protected] menulis:

Mereka dapat: const koa = require(‘koa’)

Pada 21 Jan 2016, pukul 14:47, Teoh Han Hui < [email protected] [email protected] > menulis:

Mengapa modul tanpa definisi tipe tidak dapat diimpor seperti itu?


Balas email ini secara langsung atau lihat di GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173574234.

Saya pikir poin yang dibuat adalah bahwa salah satu tujuan TypeScript adalah JS yang valid harus TS yang valid. Untuk sintaks modul ES6, TS harus mengkompilasi ini dengan atau tanpa kehadiran deklarasi tipe. Tanpa deklarasi tipe, pernyataan import seharusnya hanya diselesaikan menjadi any .

Saya sangat setuju dengan itu.

@Joe Kayu 👍

Pada 21 Jan 2016, pukul 14:52, Joe Wood [email protected] menulis:

Saya pikir poin yang dibuat adalah bahwa salah satu tujuan TypeScript adalah JS yang valid harus TS yang valid. Untuk sintaks modul ES6, TS harus mengkompilasi ini dengan atau tanpa kehadiran deklarasi tipe. Tanpa deklarasi tipe, pernyataan impor seharusnya hanya diselesaikan ke any.

Saya sangat setuju dengan itu.


Balas email ini secara langsung atau lihat di GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173575301.

FWIW perilaku ini (mengharapkan semua perpustakaan pihak ketiga diketik sebelumnya) adalah apa yang menyebabkan saya menggunakan Flow over TypeScript. Meskipun TypeScript memiliki dukungan IDE, mengharapkan segala sesuatu untuk diketik sebelumnya tidak terlalu masuk akal, terutama ketika ada banyak perpustakaan di luar sana yang:

  • Tidak dalam Pasti Diketik
  • Tidak memiliki folder ./typings
  • Saya tidak punya waktu untuk mengetiknya sendiri

Saya lebih suka tidak harus melawan sesuatu yang dimaksudkan untuk membantu perkembangan saya.

@danpantry , mengapa tidak mendeklarasikan titik masuk lib Anda saja, dan kompiler akan puas dengan itu:

declare var $: any;

Itu solusi. Tapi saya pikir itu akan menjadi ide yang baik untuk TypeScript untuk menghormati kode modul ES6 dan mundur dengan anggun. Saya tidak dapat melihat alasan bagus mengapa pernyataan impor tidak dapat mundur ke any daripada melaporkan kesalahan jika modul tingkat atas tidak diketik.

Saya lebih suka kompiler gagal lebih awal dan keras (perilaku saat ini), daripada membiarkan masalah runtime merayap tanpa diketahui. Saya lebih suka secara eksplisit memiliki baris declare var foo: any untuk menunjukkan "ini tidak aman, dan saya tahu apa yang saya lakukan".

Mengapa tidak mengizinkan sintaks impor ES6 ketika tidak ada pengetikan yang tersedia, masalah kompiler sederhana yang memperingatkan bahwa impor telah diselesaikan menjadi any , alih-alih kesalahan « emisi pencegahan »?

Pada 21 Jan 2016, pukul 18:42, S. Chris [email protected] menulis:

Saya lebih suka kompiler gagal lebih awal dan keras (perilaku saat ini), daripada membiarkan masalah runtime merayap tanpa disadari. Saya lebih suka untuk secara eksplisit memiliki pernyataan var foo: baris apa pun untuk menunjukkan "ini tidak aman, dan saya tahu apa yang saya lakukan".


Balas email ini secara langsung atau lihat di GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173649845.

Bagaimanapun, kompiler saat ini mengklaim bahwa ia tidak dapat menemukan modul, padahal sebenarnya itu hanya menolak untuk mengimpor modul tanpa definisi tipe. Itu tidak terlalu membantu, bukan?

^^^ Ini seribu kali. Tidak ada indikasi bahwa saya melakukan sesuatu yang salah ketika saya pertama kali mengalami masalah ini. Butuh beberapa lama Googling untuk akhirnya mencari tahu apa yang terjadi (kebetulan saya pikir masalah ini adalah satu-satunya tempat yang dapat ditemukan yang mendokumentasikannya). Ini sangat tidak perlu. Dan dengan Angular 2 membawa TypeScript lebih ke arus utama, saya hanya bisa membayangkan berapa banyak pertanyaan Stack Overflow yang akan datang dari perilaku ini.

Sangat setuju dengan deskripsi penanganan kesalahan yang buruk dan buat saja impor seperti apa pun!

@sccolbert Saya setuju harus ada pemberitahuan tetapi saya tidak yakin itu harus gagal - sebagai gantinya peringatan, mungkin

Saya setuju dengan @mhegazy dan @sccolbert.

Saya lebih suka skrip pembuatan produksi kami (yaitu server CI) untuk mengeluh dengan keras jika ada sesuatu yang salah.

Hai kawan,
Perilaku ini hanya membuatku gila. File definisi tidak mutakhir atau tidak terdaftar ke package.json .
Pada akhirnya TypeScript menghasilkan JavaScript , jadi, sampai kita semua pergi ke bahasa ini tolong bersikap lembut ke seluruh dunia yang menyediakan perpustakaan untuk bahasa ibu dalam bahasa transpil lainnya, seperti milik Anda .
Saya benar-benar ingin tahu apakah TypeScript ingin tetap (saya akan mengatakan "berintegrasi" karena tampaknya belum ada di sana) di ekosistem JavaScript atau ingin hidup terpisah, seperti pilihan kedua akan membuat saya untuk pergi ke sesuatu yang lain.
Untuk mencapai bahwa saklar di file .tsconfig akan dilakukan, untuk itu kita dapat mengatakan bahwa kita ingin impor ketat atau tidak.
Adapun keluhan keras CI ada kerangka uji untuk itu di JavaScript . Bagaimanapun, Anda tidak akan mendapatkan pemeriksaan tipe saat runtime, pemeriksaan impor yang buruk adalah masalah yang kurang penting untuk dimiliki.
Semua yang terbaik.

@devel-pa, kesalahan dimaksudkan untuk memberi tahu Anda bahwa kompiler tidak tahu apa impor Anda. penggunaan impor selanjutnya tidak dapat diperiksa.

Mematikan kesalahan tidak menyelesaikan masalah apa pun. itu hanya mendorong "tidak dikenal" ini secara diam-diam ke seluruh sistem Anda. tanpa informasi jenis, kompiler tidak dapat memperingatkan Anda tentang apa yang aman dan apa yang tidak. dan itulah inti dari TypeScript :)

Adapun JS yang dihasilkan. tidak ada kesalahan tipe TS yang menghentikan output Anda dari yang dihasilkan. jika Anda tidak peduli dengan kesalahan jenis, abaikan saja semuanya. kompiler masih menghasilkan file .js yang cocok.

Solusi untuk definisi yang hilang adalah dengan mendeklarasikannya. Anda tidak harus mendeklarasikan bentuk penuh modul, tetapi cukup namanya saja. Ini memungkinkan kompiler untuk mengetahui bahwa ada modul "myLibrary", ini dapat memperingatkan Anda untuk kesalahan ketik dalam nama modul, dan yang lebih penting, tidak ada modul lain yang tidak dicentang.

declare module "myLibrary" {
    var a: any;
    export = a;
}

seperti yang diuraikan di #6615, TypeScript akan segera mendukung bentuk yang lebih pendek ini.

Saya pikir masalahnya adalah rasa sakit yang disebabkan oleh proyek orientasi. Saya pikir masalah ini analog dengan implisit any . Saat ini impor ini pada dasarnya batal secara implisit . Tentu, kesalahan dapat diabaikan, tetapi itu menyebabkan banyak kebisingan dan bertentangan dengan filosofi pengetikan bertahap dan JS yang valid adalah TS yang valid.

Saya dapat memahami kebingungan di sini bagi orang-orang yang baru mengenal TS. Jika mereka secara aktif menggunakan sintaks modul ES6 di JS, mengapa tidak bekerja di TS saja? Apa yang istimewa tentang import from lebih dari var x = require - yang _is_ diperlakukan sebagai implisit apa pun. Awalnya import adalah kata kunci khusus TS, jadi ini menyiratkan bahwa pengembang ingin modul diperlakukan sebagai modul yang diketik. Sekarang itu tidak eksklusif untuk TS, saya tidak berpikir asumsi itu bisa dibuat.

implisit-setiap kesalahan ada pada deklarasi variabel tanpa tipe. tetapi menggunakan variabel yang tidak dideklarasikan masih merupakan kesalahan hari ini. Untuk jquery, Anda masih memerlukan declare var $; di suatu tempat agar kompiler mengetahui bahwa Anda benar-benar bermaksud memiliki variabel global bernama $ dan tidak hanya salah mengetiknya. itu kurang lebih sama untuk modul, compiler perlu tahu bahwa ada modul bernama "myLibrary" dan itu bukan nama yang salah ketik. jadi tambahkan saja deklarasi untuk itu.

bagaimanapun juga, #6615 harus mendukung penambahan declare module "*"; untuk mencocokkan semua modul di sistem Anda, meskipun saya pikir jika Anda melakukannya, Anda tidak mendapatkan bantuan apa pun dari perkakas Anda, dan Anda menyiapkan diri Anda untuk masalah yang menyakitkan. transisi nanti ketika Anda memutuskan untuk menghapusnya.

@mhegazy Saya mengerti alasan Anda tetapi saya benar-benar memiliki masalah dengan alasan ini

Pada dasarnya, Anda memberi tahu kami untuk merancang definisi modul "placeholder", dan masalahnya akan hilang.
Risiko ini adalah bahwa setelah beberapa saat, pada proyek berukuran wajar, definisi "placeholder" ini mungkin muncul begitu saja dan akan terkubur di beberapa direktori pengetikan. Tidak memiliki peringatan lagi, semua orang akan melupakannya dan ketika masalah muncul, melalui setiap definisi modul untuk melihat mana yang merupakan pengganti, hanya akan menyusahkan.

Situasinya bahkan lebih buruk dengan modul yang diketik (yang memiliki entri typings di package.json) yang kami anggap telah diketik dengan benar sebenarnya dapat menggunakan placeholder tersebut secara internal.

Saya mengerti bahwa placeholder ini tidak dapat dicegah, tetapi saya lebih suka bahwa, setidaknya, mereka tidak didorong.
Apa yang harus dianjurkan adalah bahwa secara default, impor diselesaikan menjadi any dan bahwa kompilator mengeluarkan peringatan pada setiap kompilasi. Jadi setidaknya, melihat kompiler/log CI, kami tahu ada sesuatu yang berpotensi mencurigakan dan perlu ditingkatkan.

(sebagai tambahan, seperti yang dinyatakan pada halaman beranda TypeScriptlang.org, TypeScript adalah 'superset' dari Javascript, dan IMHO sintaks ES6 yang valid harus ditelan apa adanya)

Solusi dan menyembunyikan sampah di bawah karpet bagi saya adalah yang terburuk yang bisa terjadi (selain ES6 super).
Saya bekerja dengan JS libs sepanjang waktu, dan biasanya dengan versi terakhir sebagai bagian dari pekerjaan saya dan pengkodean tambahan di rumah. 90% tidak diketik atau memiliki def lama, 9% tidak diketik dengan baik (karena kompilator tidak tahu untuk membuat satu def untuk semua file). Tidak ada milik saya yang memiliki def yang sangat bagus, untuk alasan sebelumnya yang sama dan karena target saya adalah JS, saya rasa saya tidak perlu peduli dengan bahasa aslinya.
Juga, saya telah melihat alasan bahwa ada lib 'tidak diketahui'. Tidak, tidak sama sekali, jika pengembang tidak tahu dan memahami lib apa yang digunakan, mengapa repot dengan mereka, saya tahu mengapa saya menggunakan barang dan mengapa saya menambahkan ke tumpukan. Peringatan dan tes (jika ada) sudah cukup untuk itu.
Tolong, JavaScript dulu, ini adalah target dan ekosistemnya. TS hanyalah aksesori untuk pengkodean dan pengecekan tipe yang lebih baik pada waktu kompilasi, tetapi hanya untuk apa yang sedang kami bangun. Selebihnya bukan urusan TypeScripts.
Saya ingin menyebutkan bahwa saya juga menentang nmps peerDependencies , sayalah yang memilih, bukan perangkat lunaknya. Pemrograman imperatif, sayang.

bagaimana dengan mengimpor modul dari direktori JSPM alih-alih node_modules?

edit: saya telah menemukan tiket yang ada -> https://github.com/Microsoft/TypeScript/issues/6012

Saya baru saja mengalami masalah dengan resolusi modul Node, saat menggunakan SystemJS untuk memuat direktori:

Rupanya, sementara Node (dan karenanya TypeScript) memahami bahwa jalur sebenarnya adalah direktori dan oleh karena itu memuat index.ts sebagai gantinya, SystemJS tidak melakukan hal seperti itu, yang berarti bahwa kode TS yang valid sebenarnya akan gagal dimuat di browser.

Hal ini juga berlaku untuk modul simpul yang memiliki titik masuk index.ts/js atau bahkan menggunakan properti package.json main . Ini sedikit lebih mudah untuk dikerjakan, karena mudah (walaupun berulang) untuk menambahkan konfigurasi paket ke SystemJS. Ini tidak mudah ketika bekerja dengan direktori sewenang-wenang.

Apa solusi yang tepat untuk ini?

Resolusi modul otomatis JSPM saat ini tidak didukung. ini dilacak oleh https://github.com/Microsoft/TypeScript/issues/6012.

Rekomendasinya adalah menggunakan dukungan resolusi modul pemetaan jalur, lihat https://github.com/Microsoft/TypeScript-Handbook/blob/release-2.0/pages/Module%20Resolution.md#path -mapping

Petunjuk di atas adalah permulaan, tetapi beberapa orang mungkin perlu melakukan sesuatu tambahan... Anda mungkin harus menambahkan
<Folder Include="node_modules" />
ke .njsproj

Info lebih lanjut

Saya sedang membangun dengan tegukan, dan TypeScriptCompileBlocked di .nsproj. Untuk memperbaiki masalah dalam men-debug breakpoint di VS 15 Pratinjau 5 (Saya mendapatkan kesalahan "bingkai tidak dalam modul") dan masalah yang saya alami dengan intellisense, saya harus menambahkan ke .njsproj . Direktori itu sudah ada di sana ketika saya mengimpor proyek, tetapi disetel ke git-ignore. Itulah teori saya tentang mengapa Visual Studio mengabaikannya (mungkin itu harus memiliki pengecualian otomatis untuk node_modules?)

Selain debugging dan kerja intellisense, saya juga berhenti melihat kesalahan intellisense di luar kesalahan persis yang sama yang saya lihat dari tegukan saat dibangun, yang diharapkan.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat