Utility Types Bawaan: Partial, Pick, Omit, Record & Kawan-kawan
Mengenal perkakas tipe bawaan TypeScript untuk mengubah bentuk tipe yang sudah ada: Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, ReturnType, Parameters, dan Awaited.
Mengapa utility types?
Dalam aplikasi, satu entitas biasanya muncul dalam beberapa "versi": data lengkap, data untuk form edit (semua opsional), data ringkas untuk daftar, dst. Menulis ulang tipe tiap versi membuatnya mudah tidak sinkron. Utility types membuat tipe baru dari tipe yang sudah ada — satu sumber kebenaran.
Semua contoh di bab ini memakai tipe ini:
interface Pengguna {
id: number
nama: string
email: string
umur?: number
}
Partial<T> — semua properti jadi opsional
function perbarui(p: Pengguna, perubahan: Partial<Pengguna>): Pengguna {
return { ...p, ...perubahan }
}
perbarui(ani, { nama: "Ani Baru" }) // ✅ cukup kirim yang berubah
Required<T> — kebalikan Partial
type PenggunaLengkap = Required<Pengguna> // umur tidak lagi opsional
Readonly<T> — semua properti tidak bisa diubah
const tetap: Readonly<Pengguna> = { id: 1, nama: "Ani", email: "a@x.id" }
tetap.nama = "Budi" // ❌ Cannot assign to 'nama' because it is a read-only property
Pick<T, Kunci> — ambil sebagian properti
type Ringkas = Pick<Pengguna, "id" | "nama"> // { id: number; nama: string }
Omit<T, Kunci> — buang sebagian properti
type FormDaftar = Omit<Pengguna, "id"> // id dibuat server, tidak ada di form
type Publik = Omit<Pengguna, "email" | "id">
Record<K, V> — object dengan kunci K dan nilai V
const stok: Record<string, number> = { apel: 10, jeruk: 4 }
type Hari = "senin" | "selasa" | "rabu"
const jadwal: Record<Hari, string[]> = {
senin: ["Matematika"],
selasa: [],
rabu: ["Fisika"], // jika ada hari yang terlewat → ERROR (kelengkapan terjaga)
}
Record dengan kunci berupa union literal adalah cara elegan membuat tabel yang wajib lengkap.
Exclude, Extract, NonNullable
type Semua = "a" | "b" | "c"
type TanpaA = Exclude<Semua, "a"> // "b" | "c"
type HanyaA = Extract<Semua, "a" | "z"> // "a"
type Pasti = NonNullable<string | null | undefined> // string
ReturnType, Parameters, Awaited
Mengambil tipe dari fungsi tanpa menulis ulang:
function buatPengguna(nama: string, umur: number) {
return { id: Math.random(), nama, umur }
}
type HasilBuat = ReturnType<typeof buatPengguna> // { id: number; nama: string; umur: number }
type ArgBuat = Parameters<typeof buatPengguna> // [nama: string, umur: number]
async function ambilAngka() { return 42 }
type Isi = Awaited<ReturnType<typeof ambilAngka>> // number (membuka Promise)
Menggabungkan utility types
// Form edit: boleh sebagian, tapi id tidak boleh diubah
type FormEdit = Partial<Omit<Pengguna, "id">>
// Data hanya-baca untuk ditampilkan
type Tampilan = Readonly<Pick<Pengguna, "nama" | "email">>
Cheat sheet
| Utility | Fungsi |
|---|---|
Partial<T> | Semua properti opsional |
Required<T> | Semua properti wajib |
Readonly<T> | Semua properti read-only |
Pick<T, K> | Hanya properti K |
Omit<T, K> | Semua kecuali K |
Record<K, V> | Object dengan kunci K, nilai V |
Exclude<U, X> / Extract<U, X> | Buang / ambil anggota union |
NonNullable<T> | Buang null & undefined |
ReturnType<F> / Parameters<F> | Tipe kembalian / parameter fungsi |
Awaited<T> | Tipe hasil dari Promise |
Kesalahan umum pemula
- Menulis ulang tipe "versi lain" secara manual padahal bisa diturunkan.
- Memakai
Partialuntuk data yang sebenarnya wajib lengkap saat disimpan — hasilnyaundefinedbocor ke database. - Mengira
Readonlymembekukan object saat runtime. Ia hanya pemeriksaan saat kompilasi (dan hanya satu tingkat / dangkal).