Union, Literal Type & Narrowing Dasar
Menggabungkan beberapa tipe dengan union (|), literal type untuk nilai yang dibatasi, type alias untuk union, dan narrowing sederhana memakai typeof.
Union type: "ini ATAU itu"
Kadang sebuah nilai boleh punya lebih dari satu kemungkinan tipe. Tanda garis tegak | menggabungkannya, dibaca "atau":
let id: string | number
id = 101 // ✅
id = "A-101" // ✅
id = true // ❌ Type 'boolean' is not assignable to type 'string | number'
Contoh nyata: ID yang kadang angka, kadang teks; hasil pencarian yang bisa ada atau tidak (Produk | null).
Masalah: hanya boleh memakai yang pasti ada
Karena id bisa string atau number, TypeScript hanya mengizinkan operasi yang valid untuk kedua tipe:
function tampil(id: string | number) {
id.toUpperCase() // ❌ Property 'toUpperCase' does not exist on type 'number'
id.toString() // ✅ ada di string maupun number
}
Narrowing: mempersempit tipe
Solusinya: periksa dulu tipenya. Di dalam blok yang sudah dicek, TypeScript mengerti tipe sebenarnya. Teknik ini disebut narrowing (mempersempit).
function format(id: string | number): string {
if (typeof id === "string") {
return id.toUpperCase() // di sini id: string
}
return id.toFixed(2) // di sini id: number
}
Operator typeof menghasilkan: "string", "number", "boolean", "bigint", "undefined", "function", "object". TypeScript memahami semuanya sebagai penjaga tipe (type guard).
Literal type: nilai spesifik sebagai tipe
Tipe tidak harus "semua string" — bisa juga hanya nilai tertentu:
let arah: "kiri" | "kanan"
arah = "kiri" // ✅
arah = "atas" // ❌ Type '"atas"' is not assignable to type '"kiri" | "kanan"'
Union dari beberapa literal memberi kita "pilihan terbatas", seperti dropdown. Jauh lebih aman daripada string bebas karena typo langsung ketahuan, dan editor menampilkan semua pilihan di autocomplete.
type Status = "menunggu" | "diproses" | "selesai" | "batal"
type Ukuran = "S" | "M" | "L" | "XL"
type Dadu = 1 | 2 | 3 | 4 | 5 | 6 // literal angka juga boleh
type Aktif = true // dan boolean
function ubahStatus(s: Status): void {
console.log("Status sekarang:", s)
}
ubahStatus("selesai") // ✅
ubahStatus("selesei") // ❌ typo ketahuan
Union dengan null / undefined
function cari(id: number): string | null {
return id === 1 ? "Ani" : null
}
const hasil = cari(2)
hasil.length // ❌ 'hasil' is possibly 'null'
if (hasil !== null) {
hasil.length // ✅
}
Cara narrowing lain yang sering dipakai
| Teknik | Contoh |
|---|---|
| Kesamaan | if (x === "kiri") { ... } |
| Truthiness | if (nama) { nama.length } (membuang null/undefined/"") |
typeof | if (typeof x === "number") |
Array.isArray | if (Array.isArray(x)) { x.length } |
Teknik yang lebih canggih (in, instanceof, discriminated union) ada di bab 8.
Kesalahan umum pemula
- Memakai
stringpadahal sebenarnya pilihannya terbatas — lebih baik literal union. - Memanggil metode khusus satu tipe pada union tanpa narrowing dulu.
- Menulis
let status = "selesai"lalu mengirimnya ke parameter bertipe literal:letmelebar jadistring. Pakaiconstatau anotasi.