Modul, import/export & File Deklarasi (.d.ts)
Memecah kode ke banyak file dengan ES modules, import type, ekspor default vs bernama, memahami file .d.ts dan paket @types, serta menambah tipe global dengan declare.
Mengapa modul?
Aplikasi nyata tidak ditulis dalam satu file. Kode dipecah menjadi banyak file kecil yang masing-masing punya satu tanggung jawab, lalu saling memakai lewat modul. TypeScript memakai sintaks modul standar JavaScript (ES Modules): export dan import.
Aturan dasarnya: sebuah file yang mengandung import atau export tingkat-atas dianggap modul — variabelnya privat untuk file itu. File tanpa keduanya dianggap skrip dengan semua deklarasi bocor ke lingkup global.
Ekspor
// matematika.ts
export const PI = 3.14159
export function luasLingkaran(r: number): number {
return PI * r * r
}
export interface Titik { x: number; y: number } // tipe juga bisa diekspor
export type Satuan = "cm" | "m"
export default class Kalkulator { // maksimal satu default per file
tambah(a: number, b: number) { return a + b }
}
Impor
// utama.ts
import Kalkulator, { PI, luasLingkaran } from "./matematika" // default + bernama
import { Titik as Koordinat } from "./matematika" // ganti nama dengan as
import * as Mat from "./matematika" // semua sebagai namespace
const k = new Kalkulator()
console.log(Mat.PI, luasLingkaran(2))
| Jenis | Ekspor | Impor |
|---|---|---|
| Bernama (banyak per file) | export const a = 1 | import { a } from "./f" |
| Default (satu per file) | export default fn | import nama from "./f" |
Ekspor bernama lebih disukai: nama konsisten di seluruh proyek, autocomplete impor otomatis bekerja, dan refactor lebih aman.
import type
Kalau yang diimpor hanya tipe (tidak dipakai sebagai nilai), tandai dengan type. Impor itu dijamin dihapus saat kompilasi dan tidak ikut jadi kode JavaScript:
import type { Titik, Satuan } from "./matematika"
import { luasLingkaran, type Titik as T2 } from "./matematika" // campuran
Re-export dan barrel file
// index.ts — satu pintu masuk untuk satu folder
export * from "./matematika"
export { default as Kalkulator } from "./matematika"
export type { Titik } from "./matematika"
File deklarasi (.d.ts)
File berakhiran .d.ts hanya berisi deklarasi tipe, tanpa kode yang dijalankan. Gunanya memberi tahu TypeScript bentuk sesuatu yang ditulis di luar TypeScript — misalnya pustaka JavaScript murni.
// pustaka-lama.d.ts
declare module "pustaka-lama" {
export function hitung(x: number): number
export const versi: string
}
Paket @types
Banyak pustaka JavaScript populer tidak menyertakan tipe. Komunitas menyediakannya lewat DefinitelyTyped, dipasang sebagai paket terpisah berawalan @types/:
npm install express
npm install --save-dev @types/express @types/node
Pustaka modern (React, Vue, Zod, Axios, dll.) sudah menyertakan tipe sendiri sehingga tidak perlu paket tambahan. Cek field types di package.json pustaka itu.
declare: memberi tahu tipe sesuatu yang sudah ada
Kata kunci declare berarti "ini sudah ada di lingkungan (dibuat tempat lain), aku hanya menjelaskan tipenya":
declare const APP_VERSION: string // disuntikkan oleh bundler
declare function gtag(...args: unknown[]): void // dari skrip pihak ketiga
Menambah tipe ke lingkup global
Dari dalam sebuah modul, gunakan declare global untuk menambah sesuatu ke global:
export {} // pastikan file ini adalah modul
declare global {
var VERSI: string // tersedia di mana saja sebagai VERSI
interface Window { tema?: string } // memperluas tipe bawaan browser
}
globalThis.VERSI = "1.0.0"
Resolusi modul (gambaran singkat)
- Path relatif (
"./f","../util") → file di proyekmu. - Nama paket (
"express") → dicari dinode_modules. - Alias seperti
"@/komponen/Tombol"→ diatur lewatpathsditsconfig.json(bab 20) dan alat build.
Catatan tentang latihan di kursus ini
Editor latihan hanya satu file, jadi import dari file lain tidak bisa dijalankan di sini. Kata kunci export pada deklarasimu tetap diterima (dihapus saat dijalankan), dan declare global bisa dicoba langsung. Latihlah import sungguhan di proyek lokalmu.
Kesalahan umum pemula
- Mencampur ekspor default dan bernama dengan nama yang berubah-ubah di tiap impor.
- Membuat circular import (A mengimpor B, B mengimpor A) — pecah ke file ketiga.
- Lupa memasang
@types/...lalu bingung dengan error "Could not find a declaration file for module".