Union & Literal Types — TypeScript

Union types memungkinkan variabel memiliki salah satu dari beberapa tipe: function cetak(id: string | number) { console.log(`ID: ${id}`); } cetak(123); // OK…

Union type artinya sebuah nilai boleh salah satu dari beberapa type: string | number dibaca "string atau number". Literal type lebih sempit lagi: type yang isinya cuma satu nilai persis, seperti "kecil". Gabungkan beberapa literal, dan kamu dapat daftar pilihan yang pasti. Mirip tombol ukuran di mesin kasir kedai kopi: kecil, sedang, besar. Kasir gak bisa memesan "jumbo", karena tombolnya memang gak ada.

🧪 Tebakan cepat: let pilihan = "kecil"; lalu let ukuran: Ukuran = pilihan;. Isinya jelas "kecil", salah satu ukuran yang boleh. Lolos atau error? Tebak dulu, jawabannya ada di bagian "let dan const memberi type yang beda".

Union: salah satu dari beberapa type

let kode: string | number = "abc";
kode = 42;   // boleh
kode = true; // error

Yang boleh kamu lakukan ke nilai union cuma hal yang bisa dilakukan ke semua anggotanya. toUpperCase() cuma ada di string, jadi ini ditolak:

function formatId(id: string | number): string {
  return id.toUpperCase(); // error
}

Pesannya: Property 'toUpperCase' does not exist on type 'string | number'. (ts(2339)). TypeScript gak tahu id itu string atau number, jadi kamu harus mengecek dulu. Pakai typeof dari JavaScript. Di dalam if yang mengecek typeof id === "string", TypeScript tahu id pasti string:

function formatId(id: string | number): string {
  if (typeof id === "string") {
    return id; // di sini id: string
  }
  return "ID-" + id; // di sini id: number
}

console.log(formatId("abc")); // abc
console.log(formatId(42));    // ID-42
Panggilan typeof id Cabang yang jalan Hasil
formatId("abc") "string" return id "abc"
formatId(42) "number" return "ID-" + id "ID-42"

Cara TypeScript mempersempit type di dalam if ini dibahas lengkap di pelajaran berikutnya, type narrowing.

Literal type: satu nilai persis

type Ukuran = "kecil" | "sedang" | "besar";

let a: Ukuran = "kecil"; // boleh
let b: Ukuran = "jumbo"; // error
let c: Ukuran = "Besar"; // error

"kecil" di sini bukan nilai, tapi type: type yang cuma boleh berisi teks "kecil". Tiga literal digabung dengan | jadi Ukuran, dan cuma tiga teks itu yang boleh masuk.

Nilai Ada di Ukuran? Kata TypeScript
"kecil" ya lolos
"jumbo" tidak Type '"jumbo"' is not assignable to type 'Ukuran'. (ts(2322))
"Besar" tidak, huruf B-nya besar Type '"Besar"' is not assignable to type 'Ukuran'. Did you mean '"besar"'? (ts(2820))
42 tidak Type '42' is not assignable to type 'Ukuran'.

Literal juga bisa angka: type Dadu = 1 | 2 | 3 | 4 | 5 | 6; menolak 7 dengan Type '7' is not assignable to type 'Dadu'. Bonusnya, editor menawarkan tiga pilihan Ukuran waktu kamu mengetik tanda kutip, jadi salah ketik ketahuan sebelum kode jalan.

let dan const memberi type yang beda

let pilihan = "kecil";   // type pilihan: string
const tetap = "kecil";   // type tetap: "kecil"

let u1: Ukuran = pilihan; // error
let u2: Ukuran = tetap;   // boleh

u1 ditolak: Type 'string' is not assignable to type 'Ukuran'. Itu jawaban tebakannya. Variabel let boleh diisi ulang nanti, misalnya pilihan = "jumbo", jadi TypeScript memberinya type yang lebih luas, string. Variabel const gak bisa diisi ulang, jadi type-nya tetap literal "kecil". Cara membetulkannya: pakai const, atau tulis type-nya langsung: let pilihan: Ukuran = "kecil";.

⚠️ Jebakan yang sering ketemu

TL;DR: Union A | B artinya nilainya boleh A atau B, misalnya string | number. Ke nilai union, kamu cuma boleh melakukan hal yang bisa dilakukan ke semua anggotanya; cek dulu dengan typeof sebelum memakai method khusus string. Literal type adalah satu nilai persis, dan type Ukuran = "kecil" | "sedang" | "besar"; cuma menerima tiga teks itu. Nilai lain ditolak dengan Type '"jumbo"' is not assignable to type 'Ukuran'. Variabel let melebar jadi string, sedangkan const tetap literal.

Yang akan kamu pelajari