Enum
Enum untuk himpunan konstanta bernama: numeric, string enum, dan kapan menghindarinya.
Analogi: Nomor Meja Bernama
Di kafe, meja punya nomor: 1, 2, 3. Tapi staf menyebutnya "meja bar", "meja jendela" supaya tidak tertukar. Enum memberi nama yang bermakna ke sekumpulan konstanta terkait, mirip memberi label ke nomor-nomor itu.
enum Arah {
Kiri, // 0
Kanan, // 1
Atas, // 2
Bawah, // 3
}
const a: Arah = Arah.Kiri;
console.log(a); // 0Numeric enum otomatis bernomor dari 0. Ada juga string enum yang nilainya eksplisit dan lebih mudah dibaca di log:
enum Metode {
GET = "GET",
POST = "POST",
}
console.log(Metode.GET); // "GET"Perilaku Mengejutkan: Enum Itu Longgar
Ini contoh yang sering bikin kaget. Numeric enum menerima ANGKA SEMBARANG tanpa protes:
enum Level { Rendah, Sedang, Tinggi }
const l: Level = 99; // tidak error! padahal 99 bukan anggota enumTidak ada error compiler di sini. Enum numeric pada dasarnya cuma number berlabel, jadi validasi "apakah nilainya anggota enum" tetap tugas kode runtime. String enum lebih ketat soal ini, tapi tetap tidak seketat literal union.
Enum vs Literal Union: Mana yang Dipilih?
Komunitas modern cenderung memilih literal union:
type Arah2 = "kiri" | "kanan" | "atas" | "bawah";Alasannya praktis: literal union tidak menghasilkan kode runtime (enum menghasilkan object JavaScript beneran), lebih ramah tree-shaking, dan pesan error-nya menunjuk nilai yang salah secara eksplisit. Enum masih masuk akal untuk interoperabilitas dengan kode lama atau saat butuh reverse mapping (Arah[0] menghasilkan "Kiri").
Kapan Dipakai di Project Nyata
- Kode numerik dari backend: status order berupa angka (0 = baru, 1 = diproses) yang butuh nama bermakna di frontend.
- Kodebase lama yang sudah memakai enum secara konsisten.
- Selain itu, pertimbangkan literal union dulu. Aturan praktis: project baru mulai dari literal union, pindah ke enum hanya bila ada alasan konkret.
Catatan teknis:
const enumdi-inline saat kompilasi sehingga tidak ada object runtime, tapi dia tidak kompatibel denganisolatedModules(yang dipakai Vite dan Next.js). Di project modern, hindariconst enumdan pilih literal union atau enum biasa.
Contoh Nyata: Kode Status dari Backend
enum StatusOrder {
Baru = 0,
Diproses = 1,
Dikirim = 2,
Selesai = 3,
}
function labelStatus(s: StatusOrder): string {
switch (s) {
case StatusOrder.Baru: return "Pesanan baru";
case StatusOrder.Diproses: return "Sedang diproses";
case StatusOrder.Dikirim: return "Dalam pengiriman";
case StatusOrder.Selesai: return "Selesai";
}
}
// API mengembalikan angka 2, langsung bermakna:
labelStatus(2); // "Dalam pengiriman"Di sinilah enum numeric bersinar: backend mengirim angka yang ringkas, frontend memakainya dengan nama yang jelas tanpa tabel pemetaan manual. Dengan literal union kamu harus mengubah angka jadi string dulu sebelum tipenya aman dipakai.
Tantangan
Enum vs union
Tulis ulang enum Level { Rendah, Sedang, Tinggi } menjadi literal union type Level2 = .... Buat fungsi label(l: Level2): string yang mengembalikan deskripsi tiap level. Bandingkan: mana yang lebih ringkas?
enum Level {
Rendah,
Sedang,
Tinggi,
}
// tulis ulang sebagai:
// type Level2 = ...
function label(l: Level2): string {
// ...
}