Saya memiliki beberapa file TypeScript:
MyClass.ts
class MyClass {
constructor() {
}
}
export = MyClass;
MyFunc.ts
function fn() { return 0; }
export = fn;
MyConsumer.ts
import * as MC from './MyClass';
import * as fn from './MyFunc';
fn();
Ini memberi saya kesalahan saat mencoba menggunakan new
Modul "MyClass" menyelesaikan entitas non-modul dan tidak dapat diimpor menggunakan konstruksi ini.
dan saat mencoba menelepon fn()
Tak dapat memanggil ekspresi yang tipenya tidak memiliki tanda tangan panggilan.
Apa yang memberi?
typescript
ecmascript-6
es6-modules
Ryan Cavanaugh
sumber
sumber
javascript
sebagai tag utama dan keluarecmascript-6
, karena tag utama di sini adalahtypescript
. Pertanyaannya salah mengasumsikan bahwaexport =
(fitur TS) dapat dipasangkanimport ... from
, sementara itu harus dipasangkanimport =
. Ini pada dasarnya adalah impor / ekspor modul ES6 vs CJS / AMD.Jawaban:
Mengapa tidak berhasil
Ini adalah
import
sintaks gaya ES6 / ES2015 . Arti sebenarnya dari ini adalah "Ambil objek ruang nama modul yang dimuat dari./MyClass
dan gunakan secara lokal sebagaiMC
". Khususnya, " objek ruang nama modul " hanya terdiri dari objek biasa dengan properti. Objek modul ES6 tidak dapat dipanggil sebagai fungsi atau dengannew
.Untuk mengatakannya lagi: Objek namespace modul ES6 tidak dapat dipanggil sebagai fungsi atau dengan
new
.Hal yang Anda
import
gunakan* as X
dari modul didefinisikan hanya memiliki properti. Dalam CommonJS downleveled ini mungkin tidak sepenuhnya dipatuhi, tetapi TypeScript memberi tahu Anda apa perilaku yang ditentukan oleh standar itu.Apa yang berhasil?
Anda harus menggunakan sintaks impor gaya CommonJS untuk menggunakan modul ini:
Jika Anda mengontrol kedua modul, Anda dapat menggunakan
export default
:MyClass.ts
MyConsumer.ts
Saya Sedih Tentang Ini; Aturannya Bodoh.
Alangkah baiknya menggunakan sintaks impor ES6, tetapi sekarang saya harus melakukan
import MC = require('./MyClass');
hal ini ? Ini sangat 2013! Kuno! Tetapi kesedihan adalah bagian normal dari pemrograman. Silakan lompat ke tahap lima dalam model Kübler-Ross: Penerimaan.TypeScript di sini memberi tahu Anda bahwa ini tidak berfungsi, karena tidak berfungsi. Ada peretasan (menambahkan
namespace
deklarasi keMyClass
adalah cara yang populer untuk menganggap ini berfungsi), dan mereka mungkin bekerja hari ini di bundler modul penurunan tingkat tertentu (misalnya rollup), tetapi ini ilusi. Belum ada implementasi modul ES6 di alam liar, tetapi itu tidak akan berlaku selamanya.Bayangkan diri Anda di masa depan, mencoba menjalankan implementasi modul ES6 asli neato dan menemukan bahwa Anda telah menyiapkan diri Anda sendiri untuk kegagalan besar dengan mencoba menggunakan sintaks ES6 untuk melakukan sesuatu yang secara eksplisit tidak dilakukan ES6 .
Saya ingin memanfaatkan pemuat modul non-standar saya
Mungkin Anda memiliki pemuat modul yang "membantu" membuat
default
ekspor jika tidak ada. Maksud saya, orang membuat standar karena suatu alasan, tetapi mengabaikan standar terkadang menyenangkan dan kami dapat berpikir itu hal yang keren untuk dilakukan.Ubah MyConsumer.ts menjadi:
Dan tentukan baris
allowSyntheticDefaultImports
perintah atautsconfig.json
opsi.Perhatikan bahwa
allowSyntheticDefaultImports
tidak mengubah perilaku waktu proses kode Anda sama sekali. Itu hanya sebuah bendera yang memberi tahu TypeScript bahwa pemuat modul Anda membuatdefault
ekspor ketika tidak ada. Ini tidak akan secara ajaib membuat kode Anda berfungsi di nodejs ketika sebelumnya tidak.sumber
export = MyClass
? Satu-satunya pilihan saya adalah mengatur modul sayacommonjs
dan terus membuat dunia menjadi tempat yang lebih buruk dengan tidak menggunakan ES modern?--esModuleInterop
, dikatakan "Kami sangat menyarankan untuk menerapkannya baik ke proyek baru maupun yang sudah ada". Menurut pendapat saya, jawaban ini (dan entri / kebijakan FAQ diDefinitelyTyped
tautan itu di sini) harus dimodifikasi untuk mencerminkan sikap baru.TypeScript 2.7 memperkenalkan dukungan dengan mengeluarkan metode pembantu baru: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-form- commonjs-modules-with --- esmoduleinterop
Jadi di tsconfig.json tambahkan dua pengaturan ini:
Dan sekarang Anda dapat menggunakan:
sumber
esModuleInterop
saya digunakanresolveJsonModule
di samping saran Anda yang lain untuk menggunakanallowSyntheticDefaultImports
dan itu berhasil untuk saya.Menambahkan 2 sen saya di sini jika orang lain mengalami masalah ini.
Cara saya mengatasi masalah ini tanpa memodifikasi
tsconfig.json
(yang dapat menjadi masalah di beberapa proyek), saya hanya menonaktifkan aturan untuk oneline.import MC = require('./MyClass'); // tslint:disable-line
sumber
Saya mendapat kesalahan ini saat mencoba memasukkan paket npm debounce dalam proyek saya.
Ketika saya mencoba solusi yang diterima di atas, saya mendapat pengecualian:
Ini akhirnya berhasil:
sumber