Enum, as const & Pilihan Nilai Terbatas
Enum numerik dan string, kapan enum cocok dan kapan sebaiknya diganti union literal, serta pola as const + keyof typeof untuk kumpulan konstanta yang aman.
Kebutuhan: sekumpulan nilai konstanta yang bernama
Sering kita punya pilihan tetap: level akses, arah mata angin, status pesanan. Menuliskannya sebagai angka/teks sembarangan ("magic value") rawan salah ketik dan sulit dibaca. TypeScript menyediakan beberapa cara rapi.
Enum numerik
enum Level {
Rendah, // 0
Sedang, // 1
Tinggi, // 2
}
const l: Level = Level.Sedang
console.log(l) // 1
console.log(Level[2]) // "Tinggi" — enum numerik bisa dibalik (reverse mapping)
enum Kode { OK = 200, NotFound = 404, Error = 500 } // nilai awal bisa diatur
Enum string
Lebih mudah dibaca saat debugging karena nilainya berupa teks bermakna:
enum Peran {
Admin = "admin",
Editor = "editor",
Tamu = "tamu",
}
function izin(p: Peran): boolean {
return p === Peran.Admin
}
izin(Peran.Admin) // true
izin("admin") // ❌ string biasa tidak diterima — harus lewat Peran.
Enum adalah salah satu dari sedikit fitur TypeScript yang menghasilkan kode JavaScript sungguhan (bukan hanya tipe yang dihapus). Karena itu sebagian tim memilih alternatif di bawah.
Alternatif 1: union literal
Seperti di bab 5 — ringan, tanpa kode tambahan:
type PeranU = "admin" | "editor" | "tamu"
function izin2(p: PeranU) { return p === "admin" }
izin2("admin") // ✅ string literal langsung diterima
Alternatif 2: object as const
Kalau kamu butuh daftar nilai yang bisa diiterasi sekaligus tipenya, pakai object konstan dengan as const. Modifier ini membuat TypeScript memperlakukan object sebagai readonly dengan tipe literal paling sempit:
const ROLE = {
ADMIN: "admin",
EDITOR: "editor",
TAMU: "tamu",
} as const
// Tanpa as const: ROLE.ADMIN bertipe string. Dengan as const: bertipe "admin".
type Role = (typeof ROLE)[keyof typeof ROLE] // "admin" | "editor" | "tamu"
function cetak(r: Role) { console.log(r) }
cetak(ROLE.ADMIN) // ✅
cetak("superuser") // ❌
Object.values(ROLE) // ["admin", "editor", "tamu"] — bisa diiterasi untuk dropdown
Baris typeof ROLE dan keyof dijelaskan penuh di bab 16. Sementara itu, hafalkan pola (typeof OBJEK)[keyof typeof OBJEK] sebagai "semua nilai object ini".
as const pada array
const HARI = ["senin", "selasa", "rabu"] as const // readonly ["senin", "selasa", "rabu"]
type Hari = (typeof HARI)[number] // "senin" | "selasa" | "rabu"
Memilih yang mana?
| Pilihan | Kelebihan | Catatan |
|---|---|---|
| Union literal | Paling sederhana, tanpa kode runtime | Tidak ada daftar nilai untuk diiterasi |
as const + tipe turunan | Nilai dan tipe dari satu sumber, bisa diiterasi | Pola yang kini paling populer |
| Enum string | Akrab bagi yang datang dari Java/C#, nama jelas | Menghasilkan kode runtime; string biasa tidak cocok |
| Enum numerik | Cocok untuk flag/kode | Nilai angka mudah salah (angka sembarang dulu diterima) |
Kesalahan umum pemula
- Lupa
as constsehingga tipe melebar jadistringdan pengecekan tidak ketat. - Memakai enum numerik lalu membandingkan dengan angka mentah (
if (l === 2)) — gunakan nama enum. - Memakai
const enumtanpa memahami batasannya pada alat build tertentu; hindari kecuali perlu.