Union & Intersection Types πΉ
Kadang hidup gak sesimpel "Hitam atau Putih". Kadang kita butuh data yang bisa berubah bentuk.
Di sini kita pake jurus Union (|) dan Intersection (&).

1. Union Types (ATAU / |) π
Simbolnya pipa |. Artinya: Variabel ini boleh Tipe A ATAU Tipe B.
// ID bisa berupa angka (101) atau string ("U-101")
let id: string | number;
id = 101; // β
Boleh
id = "U-101"; // β
Boleh
// id = true; // β Error: Boolean gak diajakType Narrowing (Penyempitan) π΅οΈ
Pas lo pake Union, TS bakal bingung: "Ini lagi jadi String atau Number?". TS bakal ngelarang lo pake method khusus string (kayak .toUpperCase) kalau dia belum yakin itu string.
Solusinya: Cek dulu (Narrowing).
function cetakId(id: string | number) {
// β Error! Number gak punya toLowerCase
// console.log(id.toLowerCase());
if (typeof id === "string") {
// β
Di dalam blok ini, TS tau id adalah STRING
console.log("ID String:", id.toUpperCase());
} else {
// β
Di sini, TS tau sisanya pasti NUMBER
console.log("ID Angka:", id.toFixed(2));
}
}2. Literal Types (Nilai Mati) π
Kita bisa kunci variabel biar isinya cuma boleh kata-kata tertentu. Ini sering banget dipake di React buat status atau tema.
// Cuma boleh isi 3 kata ini. Selain itu ERROR.
type Status = "success" | "error" | "loading";
let appStatus: Status = "loading";
// appStatus = "pending"; // β Error! "pending" gak ada di daftar.Union Type di Array
Masih ingat materi Array? Kalau lupa dibuka lagi deh!
// Array yang isinya boleh campur
const data: (string | number | boolean)[] = ["Otong", 1, true];3. Intersection Types (DAN / &) π€
Simbolnya &. Artinya: Gabungan dari Tipe A DAN Tipe B. Hasilnya adalah tipe baru yang super lengkap (Fusion).
Ini sering dipake buat Merging Objects.
type PunyaNama = { nama: string };
type PunyaSkill = { skill: string };
// Karyawan harus punya Nama DAN Skill
type Karyawan = PunyaNama & PunyaSkill;
const staff: Karyawan = {
nama: "Pian",
skill: "Coding",
// β Error kalau salah satu properti ilang.
};Contoh React Props: Kadang kita mau bikin komponen yang nerima props HTML biasa (misal id, className) TAPI ditambah props kita sendiri.
type TombolProps = React.ComponentProps<"button"> & {
variant: "primary" | "secondary"; // Props tambahan kita
};4. Discriminated Unions (Jurus Dewa) π€―
Ini pola tingkat lanjut yang sering dipake di library besar (seperti Redux). Kita punya beberapa tipe Object, tapi kita kasih satu "Tanda Pengenal" (Discriminator) yang sama.
// Tipe 1: Sapi
interface Sapi {
jenis: "sapi"; // Tanda Pengenal
melenguh: () => void;
}
// Tipe 2: Kuda
interface Kuda {
jenis: "kuda"; // Tanda Pengenal
lari: () => void;
}
type Hewan = Sapi | Kuda;
function mainHewan(hewan: Hewan) {
// TS otomatis tau method apa yang tersedia berdasarkan 'jenis'
switch (hewan.jenis) {
case "sapi":
hewan.melenguh(); // β
Aman, TS tau ini Sapi
break;
case "kuda":
hewan.lari(); // β
Aman, TS tau ini Kuda
break;
}
}Kenapa ini keren? Kalau lo tambah hewan baru (misal Ayam) tapi lupa nambahin case "ayam", TS bisa ngasih warning kalau lo pake teknik Exhaustive Check (yang kita pelajari di bab never).
Rangkuman Simbol π
| Simbol | Nama | Logika | Contoh Penggunaan |
|---|---|---|---|
| pipe | Union | ATAU (Pilih satu) | User atau Admin |
| & | Intersection | DAN (Gabung semua) | User & Admin |