Masukkan Password
12 Literal Type di TypeScript
1. Mengingat kembali Union Type
Sebelum memahami Literal Type, kita perlu ingat konsep Union Type.
Union Type digunakan ketika sebuah variabel boleh memiliki lebih dari satu tipe data.
Contohnya:
let id: string | number;
id = "ABC";
id = 123;
Artinya:
Variabel
idboleh berisistringataunumber.
Simbol | dibaca sebagai “atau” (OR).
Contoh lain:
let value: string | number | boolean;
Berarti value boleh berupa:
stringnumberboolean
Tetapi ada satu masalah.
Misalnya:
let role: string;
Dengan tipe seperti itu, kita bisa memasukkan string apa pun:
role = "admin";
role = "user";
role = "hello";
role = "abc";
role = "xyz";
TypeScript tidak akan memprotes karena semuanya adalah string.
Padahal mungkin dalam aplikasi kita hanya menginginkan role tertentu.
Misalnya:
admin
read
read-write
Nah, di sinilah Literal Type berguna.
2. Apa itu Literal Type?
Secara sederhana:
Literal Type adalah tipe data yang nilainya dibatasi pada nilai tertentu secara spesifik.
Jadi kita bukan hanya mengatakan:
“Saya ingin sebuah
string.”
Tetapi kita mengatakan:
“Saya ingin string yang nilainya harus tepat
hello world.”
Contohnya:
let message: "hello world";
Sekarang message tidak boleh diisi sembarang string.
Hanya ini yang diperbolehkan:
message = "hello world";
Sedangkan:
message = "hello";
akan menghasilkan error.
Begitu juga:
message = "Hello World";
juga error.
Karena:
"hello world"
dan
"Hello World"
adalah dua nilai yang berbeda.
3. Literal Type vs tipe biasa
Ini bagian yang sangat penting.
Perhatikan:
let str: string;
str = "hello";
str = "world";
str = "abc";
Semua boleh karena tipenya adalah:
string
Artinya:
strboleh berisi string apa pun.
Sedangkan:
let str: "hello";
Artinya:
strhanya boleh berisi string"hello".
Jadi:
| Deklarasi | Nilai yang diperbolehkan |
|---|---|
string | "hello", "world", "abc", dll |
"hello" | hanya "hello" |
number | angka berapa pun |
100 | hanya angka 100 |
boolean | true atau false |
true | hanya true |
Jadi Literal Type membuat tipe menjadi jauh lebih spesifik.
4. Kenapa const dan let bisa terlihat berbeda?
Materi tadi memberikan contoh seperti:
const str = "hello world";
Ketika kita menggunakan const, TypeScript bisa menyimpulkan bahwa nilai tersebut tidak akan berubah.
Karena:
const str = "hello world";
str tidak bisa kita ubah menjadi:
str = "hello";
Oleh karena itu TypeScript dapat memperlakukannya sebagai tipe literal:
"hello world"
Sedangkan ketika menggunakan:
let str2 = "some string";
TypeScript biasanya menyimpulkan:
string
Kenapa?
Karena let memungkinkan nilainya berubah:
let str2 = "hello";
str2 = "world";
Jadi TypeScript berpikir:
“Karena variabel ini masih bisa diubah menjadi string lain, saya anggap tipenya
string.”
5. Literal Type bisa ditulis secara eksplisit
Kita juga bisa secara langsung menentukan Literal Type:
let status: "success";
status = "success"; // OK
status = "error"; // Error
Di sini "success" bukan sekadar nilai.
Dia juga menjadi tipe.
Ini yang dimaksud dengan:
Literal value digunakan sebagai type.
6. Menggabungkan Literal Type dengan Union Type
Nah, ini adalah bagian paling penting dari materi.
Misalnya kita memiliki tiga role:
admin
read
read-write
Kita ingin sebuah variabel hanya boleh berisi salah satu dari ketiga nilai tersebut.
Kita bisa menulis:
let role: "admin" | "read" | "read-write";
Perhatikan:
"admin" | "read" | "read-write"
Ini adalah kombinasi:
- Literal Type
- Union Type
Literal Type-nya adalah:
"admin"
"read"
"read-write"
Union Type-nya adalah:
|
Sehingga:
"admin" | "read" | "read-write"
berarti:
Nilainya harus
"admin"ATAU"read"ATAU"read-write".
7. Contoh sederhana
Misalnya:
let role: "admin" | "read" | "read-write";
Maka ini valid:
role = "admin";
Valid:
role = "read";
Valid:
role = "read-write";
Tetapi ini tidak valid:
role = "user";
Dan ini juga tidak valid:
role = "guest";
Begitu juga:
role = "administrator";
akan error.
Walaupun "administrator" adalah string, tetap tidak diperbolehkan.
Karena TypeScript tidak bertanya:
“Apakah ini string?”
TypeScript bertanya:
“Apakah string ini salah satu dari nilai yang diperbolehkan?”
8. Contoh function pada materi
Sekarang kita masuk ke contoh utama dari lecture.
Kita memiliki function:
function roleMessage(role: string) {
switch (role) {
case "admin":
console.log("You have admin permission on this site");
break;
case "read":
console.log("You have read permission on this site");
break;
case "read-write":
console.log("You have read-write permission on this site");
break;
default:
console.log("Unknown user permission");
}
}
Kemudian kita bisa memanggil:
roleMessage("admin");
Output:
You have admin permission on this site
Kita juga bisa:
roleMessage("read");
Output:
You have read permission on this site
Dan:
roleMessage("read-write");
Output:
You have read-write permission on this site
Masalahnya adalah kita juga bisa melakukan:
roleMessage("abc");
atau:
roleMessage("hello");
atau bahkan:
roleMessage("banana");
TypeScript tidak akan error karena kita mengatakan:
role: string
Artinya:
“Apapun string-nya, silakan.”
9. Masalah sebenarnya ada di sini
Perhatikan function:
function roleMessage(role: string)
Kita sebenarnya tidak ingin menerima semua string.
Kita hanya ingin:
admin
read
read-write
Jadi kita ubah menjadi:
function roleMessage(
role: "admin" | "read" | "read-write"
) {
// ...
}
Sekarang TypeScript mengetahui dengan sangat jelas:
role
↓
harus "admin"
ATAU
"read"
ATAU
"read-write"
10. Apa yang terjadi kalau kita memasukkan nilai salah?
Misalnya:
roleMessage("admin");
✅ Valid.
roleMessage("read");
✅ Valid.
roleMessage("read-write");
✅ Valid.
Tetapi:
roleMessage("abc");
❌ Error.
TypeScript akan mengatakan kira-kira:
Argument of type '"abc"' is not assignable to parameter of type
'"admin" | "read" | "read-write"'
Maksudnya:
"abc"tidak termasuk nilai yang diperbolehkan untuk parameterrole.
Ini sangat membantu karena error bisa ditemukan sebelum program dijalankan.
11. Kenapa tidak cukup menggunakan string?
Pertanyaan bagusnya:
“Kan kita sudah punya
switch, kenapa harus menggunakan Literal Type?”
Karena switch hanya menangani masalah ketika program sudah berjalan.
Misalnya:
function roleMessage(role: string) {
switch (role) {
case "admin":
// ...
break;
case "read":
// ...
break;
case "read-write":
// ...
break;
default:
console.log("Unknown user permission");
}
}
Kalau seseorang memasukkan:
roleMessage("abc");
program masih berjalan.
Kemudian masuk ke:
default
dan menghasilkan:
Unknown user permission
Tetapi kalau menggunakan Literal Type:
function roleMessage(
role: "admin" | "read" | "read-write"
) {
// ...
}
maka kesalahan bisa dicegah dari awal.
roleMessage("abc");
❌ langsung ditandai error oleh TypeScript.
Jadi Literal Type berfungsi seperti pembatas atau pagar.
12. Analogi sederhana
Bayangkan kamu memiliki sebuah pintu dengan tiga kartu akses:
┌─────────────┐
│ ADMIN │
├─────────────┤
│ READ │
├─────────────┤
│ READ-WRITE │
└─────────────┘
Kalau tipe kita:
string
maka penjaganya berkata:
“Yang penting kartunya berupa kartu. Apa pun namanya boleh.”
Jadi:
ADMIN ✅
READ ✅
READ-WRITE ✅
GUEST ✅
ABC ✅
XYZ ✅
Tetapi kalau kita menggunakan:
"admin" | "read" | "read-write"
penjaganya berkata:
“Saya hanya menerima tiga kartu ini.”
Maka:
admin ✅
read ✅
read-write ✅
guest ❌
abc ❌
xyz ❌
Itulah konsep Literal Type.
13. Literal Type tidak hanya untuk string
Ini juga disebutkan dalam materi.
Literal Type tidak hanya bisa menggunakan string.
String Literal
let direction: "left" | "right";
direction = "left"; // ✅
direction = "right"; // ✅
direction = "up"; // ❌
Number Literal
Kita juga bisa menggunakan angka:
let dice: 1 | 2 | 3 | 4 | 5 | 6;
Sekarang:
dice = 1; // ✅
dice = 3; // ✅
dice = 6; // ✅
Tetapi:
dice = 7; // ❌
dice = 10; // ❌
Ini berguna misalnya untuk nilai yang memang memiliki pilihan terbatas.
14. Boolean Literal
Kita juga bisa menggunakan:
true
atau:
false
Misalnya:
let isAdmin: true;
isAdmin = true; // ✅
isAdmin = false; // ❌
Kalau kita menggunakan:
let isAdmin: boolean;
maka:
isAdmin = true;
isAdmin = false;
keduanya boleh.
Sedangkan:
let isAdmin: true;
hanya true yang diperbolehkan.
15. Perbedaan boolean dengan true
Ini penting untuk dipahami:
boolean
berarti:
true ATAU false
Sedangkan:
true
berarti:
hanya true
Sama seperti:
string
berarti semua string.
Sedangkan:
"admin"
berarti hanya string "admin".
Jadi bisa kita bayangkan seperti ini:
boolean
├── true
└── false
dan:
string
├── "admin"
├── "read"
├── "hello"
├── "abc"
└── banyak kemungkinan lainnya
Literal Type memilih satu nilai spesifik dari kemungkinan tersebut.
16. Hubungan Union Type dan Literal Type
Keduanya sebenarnya sering digunakan bersama.
Contoh:
let role: "admin" | "user" | "guest";
Di sini:
Literal Type
"admin"
"user"
"guest"
Union Type
|
Gabungannya:
"admin" | "user" | "guest"
Artinya:
rolehanya boleh memiliki salah satu dari tiga nilai tersebut.
17. Contoh yang lebih realistis
Misalnya kita membuat sistem status pesanan:
let status: "pending" | "processing" | "shipped" | "delivered";
Maka:
status = "pending"; // ✅
status = "processing"; // ✅
status = "shipped"; // ✅
status = "delivered"; // ✅
Tetapi:
status = "cancelled"; // ❌
Ini berguna karena aplikasi kita mungkin memang hanya mendefinisikan status tertentu.
18. Literal Type pada function
Kita tidak harus menggunakannya pada variabel.
Kita bisa menggunakannya langsung pada parameter function:
function move(direction: "left" | "right") {
// ...
}
Sekarang:
move("left"); // ✅
move("right"); // ✅
Tetapi:
move("up"); // ❌
move("down"); // ❌
Ini salah satu penggunaan Literal Type yang sangat umum.
19. Contoh lain: ukuran pakaian
Misalnya:
function buyShirt(size: "S" | "M" | "L" | "XL") {
console.log(`Buying size ${size}`);
}
Maka:
buyShirt("S"); // ✅
buyShirt("M"); // ✅
buyShirt("L"); // ✅
buyShirt("XL"); // ✅
Tetapi:
buyShirt("XXL"); // ❌
Karena "XXL" tidak ada dalam Literal Union Type tersebut.
20. Kenapa konsep ini penting dalam TypeScript?
Karena salah satu tujuan TypeScript adalah membuat kode lebih aman dan mudah diprediksi.
Tanpa Literal Type:
function setTheme(theme: string) {
// ...
}
Kita bisa memasukkan apa pun:
setTheme("dark");
setTheme("light");
setTheme("banana");
setTheme("abc");
Padahal aplikasi kita mungkin hanya mengenal:
dark
light
Dengan Literal Type:
function setTheme(theme: "dark" | "light") {
// ...
}
Sekarang:
setTheme("dark"); // ✅
setTheme("light"); // ✅
setTheme("banana"); // ❌
TypeScript membantu kita mencegah kesalahan tersebut.
21. Inti materi dalam satu kalimat
Kalau harus mengingat satu hal saja, ingat ini:
Literal Type digunakan ketika kita ingin membatasi sebuah nilai agar hanya boleh berupa nilai tertentu.
Contoh:
let role: "admin" | "user";
Bukan berarti:
“
roleharus berupa string.”
Tetapi:
“
roleharus tepat"admin"atau tepat"user".”
22. Ringkasan keseluruhan
Ada tiga konsep yang perlu dibedakan:
string
let role: string;
Artinya:
Boleh string apa saja.
"admin" ✅
"user" ✅
"abc" ✅
"hello" ✅
Literal Type
let role: "admin";
Artinya:
Hanya boleh
"admin".
"admin" ✅
"user" ❌
"abc" ❌
Union + Literal Type
let role: "admin" | "user" | "guest";
Artinya:
Hanya boleh
"admin","user", atau"guest".
"admin" ✅
"user" ✅
"guest" ✅
"abc" ❌
Jadi pola yang paling sering kamu lihat nanti adalah:
type Role = "admin" | "user" | "guest";
Lalu:
function login(role: Role) {
// ...
}
Ini membuat kode menjadi lebih rapi dan TypeScript dapat membantu kita memastikan hanya nilai yang benar yang digunakan.
Singkatnya: Union Type menentukan beberapa kemungkinan tipe/nilai, sedangkan Literal Type menentukan nilai yang sangat spesifik. Ketika digabungkan, kita bisa membuat daftar nilai yang secara eksplisit diperbolehkan.
Kalau kamu mau, saya juga bisa buatkan gambar/diagram visual yang menjelaskan hubungan string → Literal Type → Union Type supaya konsepnya lebih mudah diingat.