Lompat ke konten
Aback Tools Logo

Error TypeScript TS1384: Penyebab dan Solusinya

Perbaiki error TypeScript TS1384 ("modifier export tidak dapat diterapkan pada augmentasi modul"). Pelajari tiga penyebab, solusi export {}, isolatedModules, dan pola .d.ts.

DH
Tutorials & How-Tos11 menit baca2,650 kata

Error TypeScript TS1384 termasuk yang terlihat misterius saat pertama kali ditemui, tetapi selalu punya penyebab yang tepat dan bisa diperbaiki. Error ini muncul ketika kompilator menemukan modifier export di tempat yang tidak boleh, tepatnya di dalam blok augmentasi modul. Panduan ini menjelaskan arti TS1384, menelusuri setiap skenario yang memicunya, dan memberi solusi yang tepat untuk masing-masing.

TS1384Kode errorExport di augmentasi modul
1 barisPerbaikan umumexport {} mengatasi mayoritas kasus
3Penyebab utamaSkrip, isolatedModules, .d.ts

Apa itu TS1384?

Error TypeScript TS1384 membawa pesan: "modifier 'export' tidak dapat diterapkan pada augmentasi modul". Error ini muncul ketika kompilator menemukan kata kunci `export` di dalam blok `declare module` atau `declare global`, dua konstruksi yang dipakai TypeScript untuk augmentasi modul. Blok augmentasi berfungsi memperluas tipe modul yang sudah ada, bukan mendeklarasikan simbol publik baru, jadi `export` secara struktural tidak valid di dalamnya.

Augmentasi modul dalam satu kalimat

Augmentasi modul adalah mekanisme TypeScript yang memungkinkan Anda menambahkan anggota baru ke tipe modul yang sudah ada: misalnya menambahkan properti khusus ke `Express.Request`, memperluas `Window` dengan global pihak ketiga, atau menambahkan metode ke opsi komponen sebuah framework. Sintaksnya mirip blok `declare module 'nama-modul' {}` dan harus berada di file modul (file dengan setidaknya satu pernyataan `import` atau `export` tingkat atas).

  • TS1384 adalah error kompilator: file tidak akan lolos pemeriksaan tipe sampai diperbaiki
  • Tidak memengaruhi runtime: error ini murni soal deklarasi tipe
  • Bersifat deterministik: kode yang sama selalu memicunya, tidak ada versi yang muncul-hilang
  • Penyebabnya sedikit: konteks skrip versus modul, isolatedModules, dan struktur .d.ts yang salah mencakup 95% kasus

Note

TS1384 terkait tetapi berbeda dari TS2669 ("augmentasi untuk scope global hanya dapat disarangkan langsung di modul eksternal atau deklarasi modul ambient"). Keduanya berasal dari konteks file yang salah untuk sintaks augmentasi dan keduanya diperbaiki dengan teknik `export {}` yang sama; namun TS2669 dipicu oleh posisi blok `declare global`, sedangkan TS1384 dipicu khusus oleh modifier `export` di dalam augmentasi.

Kapan TS1384 muncul

Error ini selalu melibatkan `export` di tempat yang tidak diizinkan TypeScript. Ada tiga pola berbeda yang menghasilkannya, dan mengenali pola mana yang berlaku di kode Anda menentukan perbaikan yang tepat.

Pola 1: export di dalam blok declare module

Pemicu paling langsung: Anda menulis pernyataan `export` di dalam augmentasi `declare module`. Niatnya biasanya menambahkan sesuatu ke API publik modul, tetapi blok augmentasi tidak bekerja seperti itu: ia hanya bisa memperluas deklarasi tipe yang sudah ada di modul target.

typescript
// ✗ TS1384 - export di dalam augmentasi modul
declare module 'some-library' {
  export interface NewInterface {   // <-- TS1384 muncul di sini
    id: string;
  }
}

// ✓ Benar - interface ditambahkan tanpa export
declare module 'some-library' {
  interface ExistingInterface {
    newProperty: string;            // memperluas tipe yang ada
  }
}

Pola 2: file diperlakukan sebagai skrip, bukan modul

Ini penyebab TS1384 paling umum di proyek nyata. Jika sebuah file tidak punya pernyataan `import` atau `export` tingkat atas, TypeScript memperlakukannya sebagai skrip dengan scope global. Blok `declare global {}` di file skrip tidak bermakna (di skrip semuanya sudah global), sehingga TypeScript menolak setiap `export` di dalamnya dengan TS1384. File tersebut harus berupa modul agar konteks augmentasinya masuk akal.

Pola 3: struktur file .d.ts yang salah

File deklarasi (`.d.ts`) yang mencampur deklarasi modul ambient dengan pernyataan `export` biasa dalam urutan yang salah bisa memicu TS1384. File `.d.ts` yang dimulai dengan deklarasi `export` tingkat atas lalu berisi blok `declare module` diperlakukan sebagai modul, dan itu benar. Tetapi `.d.ts` yang membungkus semuanya dalam satu blok `declare module` lalu mencoba memakai `export` di dalam blok itu mencampur konteks augmentasi dengan konteks definisi modul.

Warning

TS1384 juga bisa berasal dari **paket pihak ketiga** yang mengirim file `.d.ts` rusak. Jika error menunjuk ke path di dalam `node_modules`, sumbernya adalah dependensi, bukan kode Anda. Perbaikannya dalam kasus itu adalah `skipLibCheck: true` di tsconfig.json, bukan mengubah file paket.

Cara memperbaiki TS1384: augmentasi modul

Perbaikan yang tepat bergantung pada apa yang sebenarnya ingin Anda capai. Ada dua tujuan berbeda yang bisa mengarah ke TS1384 dan keduanya butuh pendekatan berbeda. Ikuti empat langkah ini untuk menyelesaikan error dengan bersih.

1

Identifikasi pola mana yang memicu TS1384

Baca pesan kompilator lengkap dengan saksama. Perhatikan ekstensi file (.ts atau .d.ts), nomor baris, dan apakah `export` berada di blok `declare module`, blok `declare global`, atau di tempat lain. Konteks kode di sekitarnya memberi tahu pola mana dari tiga di atas yang berlaku. Jika path error diawali `node_modules/`, langsung ke perbaikan `skipLibCheck`: pola lain tidak berlaku.

2

Tambahkan export {} untuk mengubah file menjadi modul

Jika file Anda punya blok `declare module` atau `declare global` tetapi tidak punya import atau export tingkat atas, tambahkan `export {}` di bagian atas. Satu baris ini mengubah file dari konteks skrip ke konteks modul, lingkungan yang diwajibkan untuk sintaks augmentasi. Export kosong ini tidak menambah apa pun ke hasil kompilasi: ia murni sinyal konteks untuk TypeScript.

src/types/global.d.ts
typescript
// Tambahkan baris ini agar file menjadi modul
export {};

declare global {
  interface Window {
    myAnalytics: AnalyticsInstance;
  }
}
3

Pindahkan declare global ke modul yang sudah ada

Alternatif dari menambah `export {}` adalah menempatkan blok `declare global` di file yang sudah punya import atau export nyata, seperti titik masuk library, modul fitur, atau file utilitas bersama. Pendekatan ini menjaga augmentasi tipe tetap dekat dengan kode yang diperluasnya, dan itu bisa lebih mudah dipelihara daripada file deklarasi global khusus.

4

Hapus export dari dalam blok augmentasi

Jika Anda benar-benar ingin menambahkan tipe yang bisa diekspor ke API publik modul yang sudah ada, blok augmentasi bukan tempat yang tepat. Pindahkan deklarasi sepenuhnya ke luar blok `declare module`. Untuk memperluas interface yang sudah ada, gunakan nama interface yang sama tanpa `export` di dalam blok: TypeScript akan menggabungkannya otomatis lewat declaration merging.

Format dan Validator JSON

Validasi tsconfig.json dan package.json Anda untuk error sintaks secara instan di browser, tanpa perlu kompilator TypeScript.

Open tool

TS1384 dan isolatedModules

Opsi kompilator `isolatedModules` aktif secara default di Vite, Next.js, Create React App dengan Babel, dan proyek apa pun yang memakai esbuild atau SWC. Opsi ini mewajibkan setiap file bisa ditransformasi secara mandiri tanpa informasi tipe antar file, yang menambah batasan dan memperkuat beberapa error TypeScript, termasuk TS1384.

Apa yang dibatasi isolatedModules

KonstruksiTanpa isolatedModulesDengan isolatedModules
`const enum`✓ Diizinkan di mana saja✗ Hanya di file .d.ts
`export type`✓ Opsional✓ Wajib untuk re-export khusus tipe
`import type`✓ Opsional✓ Wajib untuk import khusus tipe
Deklarasi ambient✓ Di file .ts mana pun✓ Lebih baik di file .d.ts
Augmentasi modul✓ Di file .ts modul✓ Sebaiknya di file .d.ts
Re-export namespace✓ Diizinkan✗ Dibatasi

Perbaikan khusus isolatedModules

Ketika `isolatedModules` aktif dan TS1384 muncul pada augmentasi di file `.ts` biasa, perbaikan terbersihnya adalah memindahkan augmentasi ke file `.d.ts`. File deklarasi tidak pernah ditransformasi oleh esbuild atau Babel: hanya kompilator TypeScript yang membacanya. Ini menghapus batasan isolatedModules sepenuhnya untuk augmentasi tersebut.

src/types/express.d.ts
typescript
// Pola ini bekerja dengan benar bersama isolatedModules
export {};

declare module 'express' {
  interface Request {
    userId?: string;
    tenantId?: string;
  }
}

Tip

Jika Anda tidak yakin apakah `isolatedModules` aktif di proyek Anda, cari `"isolatedModules": true` di tsconfig.json. Cek juga konfigurasi bundler: template tsconfig default Vite menyertakannya dan Next.js mengaktifkannya otomatis saat memakai SWC. Gunakan [Penampil perbedaan](/tools/data/dev-utilities/diff-viewer) untuk membandingkan tsconfig Anda dengan acuan yang dikenal saat mendiagnosis masalah TS1384 yang spesifik pada suatu lingkungan.

TS1384 di file .d.ts

File deklarasi menambahkan nuansa tersendiri pada TS1384. Aturan tentang apa yang valid di file `.d.ts` sedikit berbeda dari file `.ts` biasa, dan pola yang menghasilkan TS1384 di file deklarasi sering kali kurang intuitif.

Definisi modul ambient atau augmentasi?

File `.d.ts` bisa memuat dua hal yang tampak mirip tetapi berperilaku berbeda. Definisi modul ambient (`declare module 'nama' {}` di `.d.ts` dalam konteks skrip, tanpa import atau export) mendefinisikan seluruh tipe sebuah modul dari nol: ini dipakai untuk memberi tipe pada library JavaScript yang belum bertipe. Augmentasi modul (`declare module 'nama' {}` di `.d.ts` dalam konteks modul dengan `export {}`) memperluas tipe modul yang sudah ada. Perbedaannya penting karena `export` valid di definisi modul ambient, tetapi menghasilkan TS1384 di augmentasi modul.

Memilih pola .d.ts yang tepat

Jika file `.d.ts` Anda mendefinisikan tipe untuk library tanpa tipe (misalnya memberi tipe pada plugin jQuery lama), biarkan sebagai file konteks skrip tanpa `export {}` di awal. Pakai `export` dengan bebas di dalam blok `declare module`. Jika file `.d.ts` Anda memperluas library yang sudah bertipe (misalnya menambahkan properti ke `Express.Request`), tambahkan `export {}` di awal dan hapus setiap `export` dari dalam blok `declare module`.

Note

Cara cepat menentukan pola yang berlaku: jika modul target sudah punya definisi tipe (lewat `@types/...` atau bawaan), Anda sedang melakukan augmentasi. Jika modul itu sama sekali tidak bertipe dan Anda membuat tipenya dari nol, Anda sedang menulis definisi modul ambient.

skipLibCheck sebagai jalan terakhir

Ketika TS1384 muncul pada path di dalam `node_modules` dan Anda tidak mengendalikan paket tersebut, tambahkan `"skipLibCheck": true` ke tsconfig.json. Ini meminta TypeScript melewati pemeriksaan tipe semua file `.d.ts`, termasuk yang ada di `node_modules`. Ini opsi konfigurasi yang sah dan banyak dipakai, bukan trik. Konsekuensinya, Anda kehilangan sepenuhnya pemeriksaan tipe pada deklarasi library, sehingga tipe yang benar-benar rusak di dependensi tidak akan dilaporkan. Pakai `skipLibCheck` hanya bila alternatifnya adalah build Anda tersendat.

TS1384 di framework dan bundler

Setiap framework dan alat build mengonfigurasi TypeScript dengan cara berbeda, jadi TS1384 bisa muncul karena alasan yang sedikit berbeda tergantung stack Anda. Berikut bagaimana lingkungan yang paling umum menghasilkan dan mengatasi error ini.

Next.js

Next.js mengaktifkan `isolatedModules` otomatis lewat tsconfig defaultnya dan memakai SWC untuk transformasi. Pola standar untuk augmentasi tipe di Next.js adalah direktori `types/` khusus di root proyek berisi file `.d.ts` yang dimulai dengan `export {}`. Next.js juga menghasilkan file `next-env.d.ts`: jangan pernah mengeditnya manual, karena file itu dibuat ulang setiap build dan perubahan Anda akan hilang. Letakkan augmentasi Anda di file terpisah.

Vite

Proyek Vite memakai esbuild untuk transformasi dan menyertakan `isolatedModules: true` di tsconfig default. Vite juga menghasilkan file `vite-env.d.ts` untuk global miliknya. Letakkan augmentasi modul di direktori `src/types/` terpisah. Pola `export {}` mengatasi TS1384 di semua pengaturan Vite standar, dan menyimpan augmentasi di file `.d.ts` adalah pendekatan paling aman ketika transformasi esbuild ada di rantai proses.

API Node.js / Express biasa

Proyek Express sering memperluas `Express.Request` untuk menambahkan sesi pengguna atau konteks autentikasi. Pola kanonisnya adalah file `src/types/express/index.d.ts` dengan `export {}` di awal lalu augmentasi `declare module 'express-serve-static-core'`. Tanpa `isolatedModules`, ini juga berfungsi sebagai file `.ts` biasa, tetapi memakai `.d.ts` adalah konvensi yang lebih bersih dalam semua kasus. Selalu verifikasi nama modul yang tepat di definisi tipe Express, karena target augmentasinya adalah `express-serve-static-core`, bukan `express`.

File harus berupa modul sebelum bisa mengaugmentasi modul lain. Satu `export {}` mengubah skrip menjadi modul, dan membuka seluruh sistem augmentasi.

- Prinsip augmentasi modul TypeScript

Menghindari TS1384 dalam jangka panjang

TS1384 mudah muncul tanpa sengaja, terutama saat anggota tim baru menambahkan augmentasi tipe atau ketika Anda memigrasi proyek ke bundler baru. Praktik berikut mencegahnya kembali setelah diperbaiki.

Tetapkan konvensi direktori tipe

Buat direktori `src/types/` (atau `types/`) dan simpan semua augmentasi modul di sana sebagai file `.d.ts`. Setiap file sebaiknya memuat satu augmentasi dan dimulai dengan `export {}`. Dokumentasikan konvensi ini di `CONTRIBUTING.md` proyek agar kontributor baru tahu di mana deklarasi tipe diletakkan. Lokasi yang konsisten juga memudahkan audit augmentasi saat memperbarui dependensi.

Gunakan tsc --noEmit di CI

Menjalankan `tsc --noEmit` sebagai langkah CI menangkap TS1384 (dan error TypeScript lainnya) sebelum kode masuk ke main. Banyak proyek melewati pemeriksaan tipe di CI karena bundler tidak mewajibkannya: esbuild dan SWC membuang tipe tanpa memeriksanya. Tambahkan `tsc --noEmit` sebagai langkah terpisah agar error tipe, termasuk TS1384, tertangkap di setiap pull request.

Audit perubahan tsconfig dengan penampil perbedaan

Perubahan pada tsconfig.json, seperti menambahkan `isolatedModules`, mengganti `moduleResolution`, atau memperbarui `lib`, bisa memunculkan TS1384 di file yang sebelumnya terkompilasi bersih. Saat ada perubahan tsconfig, gunakan Penampil perbedaan untuk membandingkan konfigurasi lama dan baru berdampingan. Dengan begitu langsung terlihat opsi mana yang berubah, dan Anda bisa melacak error TS1384 baru ke pengaturan spesifik yang menyebabkannya.

Tip

Setelah memperbaiki TS1384, validasi sintaks tsconfig.json Anda dengan [Format dan Validator JSON](/tools/data/formatters/json-formatter-viewer): file tsconfig adalah JSON, dan koma di akhir atau tanda kutip yang hilang diam-diam mencegah TypeScript membaca perubahan konfigurasi yang baru Anda buat.

Penampil perbedaan

Bandingkan dua versi tsconfig.json, package.json, atau file teks apa pun berdampingan untuk melihat tepat apa yang berubah, di browser dan tanpa perlu mengunggah.

Open tool

Key takeaways

  • TS1384 muncul ketika modifier `export` berada di dalam blok augmentasi `declare module` atau `declare global`; perbaikannya hampir selalu satu baris.
  • Penyebab paling umum: file tidak punya import atau export, jadi TypeScript memperlakukannya sebagai skrip. Tambahkan `export {}` di awal untuk mengubahnya menjadi modul.
  • Dengan `isolatedModules: true` (proyek Vite, Next.js, esbuild), pindahkan augmentasi ke file `.d.ts`: file itu dikecualikan dari transformasi dan sepenuhnya menghindari batasan.
  • Jika TS1384 menunjuk ke path di dalam `node_modules`, perbaikannya adalah `skipLibCheck: true` di tsconfig.json: Anda tidak bisa mengedit file deklarasi dependensi.
  • Definisi modul ambient (memberi tipe pada library tanpa tipe) dan augmentasi modul (memperluas library bertipe) terlihat mirip tetapi berbeda: `export` di dalam blok hanya valid pada definisi, bukan augmentasi.
  • Tambahkan `tsc --noEmit` ke pipeline CI untuk menangkap TS1384 di setiap pull request, meskipun bundler Anda (esbuild, SWC) tidak melakukan pemeriksaan tipe saat build.
  • Validasi sintaks tsconfig.json dengan Format dan Validator JSON setelah perubahan: error sintaks JSON diam-diam mencegah TypeScript membaca konfigurasi Anda.

Pertanyaan yang sering diajukan

TS1384 berarti TypeScript menemukan modifier `export` di tempat yang tidak diizinkan, tepatnya di dalam blok augmentasi modul. Pesan lengkapnya: "modifier 'export' tidak dapat diterapkan pada augmentasi modul". Augmentasi modul memperluas tipe yang sudah ada dengan `declare module '...' {}` atau `declare global {}`. Augmentasi tidak bisa mengekspor simbol baru: ia hanya menambahkan deklarasi ke modul yang sudah ada. Setiap `export` di dalam blok augmentasi memicu TS1384.

Perbaikan paling umum adalah memastikan file tersebut adalah modul, bukan skrip. Tambahkan `export {}` di bagian atas jika file tidak punya import atau export lain. Ini mengubahnya dari konteks skrip menjadi konteks modul, yang diwajibkan TypeScript untuk sintaks augmentasi `declare module` dan `declare global`. Jika Anda ingin menambah tipe baru alih-alih memperluas tipe yang ada, pindahkan deklarasi tipe ke luar blok `declare module`.

Blok `declare global {}` harus berada di file yang sudah dianggap modul oleh TypeScript, yaitu setidaknya punya satu `import` atau `export` tingkat atas. Tanpa itu, TypeScript memperlakukan file sebagai skrip, dan `declare global` di file skrip menghasilkan TS1384. Tambahkan `export {}` di akhir file untuk memaksa mode modul tanpa benar-benar mengekspor apa pun. Ini pola standar untuk file augmentasi tipe global.

File TypeScript adalah skrip jika tidak punya pernyataan `import` atau `export` tingkat atas: deklarasi di skrip berbagi scope global yang terlihat oleh semua file skrip lain. File dengan setidaknya satu `import` atau `export` adalah modul dengan scope sendiri yang terisolasi. Sintaks augmentasi modul hanya diizinkan di file modul. Menambahkan `export {}`, yaitu export kosong, mengubah skrip menjadi modul dan mengatasi TS1384 tanpa mengubah perilaku saat runtime.

Ya, dalam skenario tertentu. Dengan `isolatedModules: true` di tsconfig.json, TypeScript mewajibkan setiap file bisa ditransformasi secara mandiri. Augmentasi yang hanya berisi tipe di file .ts biasa bisa memicu TS1384 saat esbuild atau Babel memprosesnya, karena alat tersebut tidak bisa menyelesaikan informasi tipe antar file. Memindahkan augmentasi ke file .d.ts menyelesaikannya: file deklarasi dikecualikan dari transformasi oleh semua bundler utama.

Bisa. Jika sebuah paket mengirim deklarasi tipe yang salah karena memakai `export` di dalam blok augmentasi modul, proyek Anda memunculkan TS1384 saat TypeScript membaca deklarasi tersebut. Perbaikan pragmatisnya adalah menambahkan `skipLibCheck: true` ke tsconfig.json, yang melewati pemeriksaan tipe file deklarasi di node_modules. Ini hanya solusi sementara: perbaikan yang benar adalah penulis paket memperbaiki deklarasinya. Pertimbangkan membuka issue di repositori paket dengan konteks TS1384 yang spesifik.

TS2669 ("augmentasi untuk scope global hanya dapat disarangkan langsung di modul eksternal atau deklarasi modul ambient") sangat erat kaitannya. Kedua error muncul saat konteks file tidak cocok untuk augmentasi modul. TS1384 muncul ketika modifier `export` berada di dalam blok augmentasi itu sendiri; TS2669 muncul ketika blok `declare global {}` berada di file skrip bukan modul. Solusinya identik untuk keduanya: tambahkan setidaknya satu pernyataan `import` atau `export` pada file tersebut.

Jalankan `tsc --noEmit` dari root proyek: TypeScript akan memvalidasi tsconfig.json dan melaporkan error konfigurasi tanpa menghasilkan file keluaran. Untuk error sintaks JSON di tsconfig.json itu sendiri (koma hilang, koma di akhir, nama properti salah), tempelkan isi file ke Format dan Validator JSON dari Aback Tools, yang langsung menandai masalah sintaks di browser tanpa perlu memasang kompilator TypeScript.

ShareXLinkedIn