SEJATIDIMEDIA Logo
Tersedia Sesi Konsultasi Gratis
SejatiDimedia Logo

Utility Types yang Wajib Diketahui Setiap Developer TypeScript

Artikel penutup Series 1 ini ngebahas kumpulan utility types bawaan TypeScript yang paling sering dipake di proyek nyata, kayak `Partial`, `Required`, `Pick`, `Omit`, `Record`, dan `ReturnType`. Setiap utility type dijelasin lewat use case konkret, misalnya `Partial` buat bikin form update yang field-nya opsional, `Omit` buat bikin DTO dari model database, dan `Record` buat bikin mapping objek yang type safe. Di akhir artikel ada juga pengenalan singkat cara bikin utility type sendiri, sebagai jembatan menuju Series 2 yang bahas type level programming lebih dalam.

Timur Dian Radha Sejati

Timur Dian Radha Sejati

Founder SejatiDimedia•25 September 2026•5 menit baca
Silabus Seri Rekayasa

TypeScript Fundamentals

Series ini dirancang untuk membangun fondasi TypeScript yang kuat bagi pembaca yang baru mulai belajar atau ingin memperkuat pemahaman dasarnya. Dimulai dari alasan mendasar kenapa TypeScript layak dipelajari dibanding JavaScript murni, lanjut ke konsep-konsep inti seperti perbedaan any, unknown, dan never, cara kerja type inference, union dan intersection type, generics, hingga utility types yang paling sering dipakai di proyek nyata. Setiap artikel ditulis dengan pendekatan step by step, disertai contoh kode dan studi kasus dunia nyata, sehingga pembaca tidak hanya tahu "apa" tapi juga paham "kenapa" di balik setiap konsep. Series ini menjadi pondasi sebelum masuk ke topik yang lebih advance seperti type level programming dan pola arsitektur TypeScript di Series berikutnya.

Lihat Silabus Lengkap
Utility Types yang Wajib Diketahui Setiap Developer TypeScript

Kalau kamu udah sering nulis interface atau type di TypeScript, pasti pernah ngalamin situasi kayak gini. Kamu punya satu interface utama, terus butuh versi lain dari interface itu yang dikit beda, misalnya semua field-nya jadi opsional, atau ada beberapa field yang dihilangin. Daripada nulis interface baru dari nol dan duplikasi banyak kode, TypeScript udah nyediain kumpulan utility types buat nanganin kasus-kasus umum kayak gini.

Di artikel ini kita bakal bahas enam utility types yang paling sering kepake di proyek nyata.

Partial, Bikin Semua Properti Jadi Opsional

Bayangin kamu punya interface

PLAINTEXT Snippetplaintext
1
User
1 baris•4 chars
UTF-8•Spaces: 4
:

index.tstypescript
1
interface User {
2
id: string;
3
nama: string;
4
email: string;
5
}
5 baris•65 chars
UTF-8•Spaces: 4

Sekarang kamu mau bikin fungsi update, di mana user cuma perlu ngirim field yang mau diubah aja, gak wajib semua.

index.tstypescript
1
function updateUser(id: string, data: Partial<User>) {
2
// ...
3
}
4
 
5
updateUser("1", { nama: "Andi Baru" }); // aman, cuma nama aja yang diisi
6
updateUser("1", { email: "andi@mail.com" }); // aman juga
6 baris•198 chars
UTF-8•Spaces: 4

PLAINTEXT Snippetplaintext
1
Partial<User>
1 baris•13 chars
UTF-8•Spaces: 4
bikin semua properti di
PLAINTEXT Snippetplaintext
1
User
1 baris•4 chars
UTF-8•Spaces: 4
jadi opsional. Tanpa
PLAINTEXT Snippetplaintext
1
Partial
1 baris•7 chars
UTF-8•Spaces: 4
, kamu harus ngirim
PLAINTEXT Snippetplaintext
1
id
1 baris•2 chars
UTF-8•Spaces: 4
,
PLAINTEXT Snippetplaintext
1
nama
1 baris•4 chars
UTF-8•Spaces: 4
, dan
PLAINTEXT Snippetplaintext
1
email
1 baris•5 chars
UTF-8•Spaces: 4
sekaligus tiap kali manggil
PLAINTEXT Snippetplaintext
1
updateUser
1 baris•10 chars
UTF-8•Spaces: 4
, padahal maksudnya cuma mau update satu field doang.

Required, Kebalikan dari Partial

Kalau

PLAINTEXT Snippetplaintext
1
Partial
1 baris•7 chars
UTF-8•Spaces: 4
bikin semua opsional,
PLAINTEXT Snippetplaintext
1
Required
1 baris•8 chars
UTF-8•Spaces: 4
justru bikin semua properti jadi wajib, bahkan kalau di interface aslinya ada yang optional.

index.tstypescript
1
interface Filter {
2
kategori?: string;
3
minHarga?: number;
4
maxHarga?: number;
5
}
6
 
7
function terapkanFilterLengkap(filter: Required<Filter>) {
8
console.log(filter.kategori, filter.minHarga, filter.maxHarga);
9
}
10
 
11
terapkanFilterLengkap({ kategori: "baju", minHarga: 0, maxHarga: 100000 }); // aman
12
terapkanFilterLengkap({ kategori: "baju" }); // Error, minHarga dan maxHarga wajib
12 baris•379 chars
UTF-8•Spaces: 4

Ini kepake kalau kamu punya interface yang field-nya opsional buat kasus umum, tapi ada fungsi spesifik yang butuh semua field-nya keisi lengkap.

Pick, Ambil Beberapa Properti Aja

PLAINTEXT Snippetplaintext
1
Pick
1 baris•4 chars
UTF-8•Spaces: 4
dipake kalau kamu cuma butuh sebagian properti dari sebuah tipe, bukan semuanya.

index.tstypescript
1
interface Produk {
2
id: string;
3
nama: string;
4
harga: number;
5
stok: number;
6
deskripsi: string;
7
}
8
 
9
type ProdukRingkas = Pick<Produk, "id" | "nama" | "harga">;
10
 
11
const kartuProduk: ProdukRingkas = {
12
id: "p1",
13
nama: "Baju",
14
harga: 100000,
15
};
15 baris•251 chars
UTF-8•Spaces: 4

PLAINTEXT Snippetplaintext
1
ProdukRingkas
1 baris•13 chars
UTF-8•Spaces: 4
di sini cuma punya tiga properti dari
PLAINTEXT Snippetplaintext
1
Produk
1 baris•6 chars
UTF-8•Spaces: 4
, cocok buat kasus kayak nampilin kartu produk di halaman katalog, di mana kamu gak butuh
PLAINTEXT Snippetplaintext
1
stok
1 baris•4 chars
UTF-8•Spaces: 4
atau
PLAINTEXT Snippetplaintext
1
deskripsi
1 baris•9 chars
UTF-8•Spaces: 4
lengkap.

Omit, Kebalikan dari Pick

Kalau

PLAINTEXT Snippetplaintext
1
Pick
1 baris•4 chars
UTF-8•Spaces: 4
milih properti mana yang mau diambil,
PLAINTEXT Snippetplaintext
1
Omit
1 baris•4 chars
UTF-8•Spaces: 4
justru milih properti mana yang mau dibuang.

index.tstypescript
1
interface ProdukDenganTimestamp {
2
id: string;
3
nama: string;
4
harga: number;
5
createdAt: Date;
6
updatedAt: Date;
7
}
8
 
9
type ProdukDTO = Omit<ProdukDenganTimestamp, "createdAt" | "updatedAt">;
10
 
11
const dataInput: ProdukDTO = {
12
id: "p1",
13
nama: "Baju",
14
harga: 100000,
15
};
15 baris•274 chars
UTF-8•Spaces: 4

PLAINTEXT Snippetplaintext
1
Omit
1 baris•4 chars
UTF-8•Spaces: 4
ini super berguna buat bikin DTO (Data Transfer Object) dari model database. Biasanya model database punya field kayak
PLAINTEXT Snippetplaintext
1
createdAt
1 baris•9 chars
UTF-8•Spaces: 4
dan
PLAINTEXT Snippetplaintext
1
updatedAt
1 baris•9 chars
UTF-8•Spaces: 4
yang di-generate otomatis sama sistem, jadi gak perlu diisi manual pas kamu bikin data baru. Daripada nulis interface baru dari nol, tinggal
PLAINTEXT Snippetplaintext
1
Omit
1 baris•4 chars
UTF-8•Spaces: 4
field yang gak dibutuhin dari model aslinya.

Record, Bikin Mapping Objek yang Type Safe

PLAINTEXT Snippetplaintext
1
Record
1 baris•6 chars
UTF-8•Spaces: 4
dipake buat bikin tipe objek yang key dan value-nya udah ditentuin polanya dari awal.

index.tstypescript
1
type StatusPesanan = "pending" | "diproses" | "selesai" | "dibatalkan";
2
 
3
const labelStatus: Record<StatusPesanan, string> = {
4
pending: "Menunggu Pembayaran",
5
diproses: "Sedang Diproses",
6
selesai: "Pesanan Selesai",
7
dibatalkan: "Pesanan Dibatalkan",
8
};
8 baris•259 chars
UTF-8•Spaces: 4

Yang keren dari

PLAINTEXT Snippetplaintext
1
Record<StatusPesanan, string>
1 baris•29 chars
UTF-8•Spaces: 4
, TypeScript bakal maksa kamu ngisi semua kemungkinan
PLAINTEXT Snippetplaintext
1
StatusPesanan
1 baris•13 chars
UTF-8•Spaces: 4
sebagai key. Kalau kamu lupa satu aja, misalnya lupa nulis
PLAINTEXT Snippetplaintext
1
dibatalkan
1 baris•10 chars
UTF-8•Spaces: 4
, TypeScript bakal langsung error. Ini beda banget kalau kamu cuma pake object literal biasa tanpa
PLAINTEXT Snippetplaintext
1
Record
1 baris•6 chars
UTF-8•Spaces: 4
, di mana lupa satu key gak bakal ketahuan sampai kode dijalankan dan ternyata ada status yang gak punya label.

ReturnType, Ambil Tipe dari Return Value Fungsi

PLAINTEXT Snippetplaintext
1
ReturnType
1 baris•10 chars
UTF-8•Spaces: 4
dipake buat "nyolong" tipe dari return value sebuah fungsi, tanpa kamu perlu nulis ulang tipe itu secara manual.

index.tstypescript
1
function buatUser(nama: string, umur: number) {
2
return {
3
id: crypto.randomUUID(),
4
nama,
5
umur,
6
createdAt: new Date(),
7
};
8
}
9
 
10
type UserResult = ReturnType<typeof buatUser>;
11
// otomatis sama kayak:
12
// { id: string; nama: string; umur: number; createdAt: Date }
13
 
14
function tampilkanUser(user: UserResult) {
15
console.log(user.nama);
16
}
16 baris•348 chars
UTF-8•Spaces: 4

Ini berguna banget kalau bentuk data yang di-return sebuah fungsi cukup kompleks dan kemungkinan bakal berubah di masa depan. Daripada nulis interface terpisah yang harus kamu update manual tiap kali fungsi

PLAINTEXT Snippetplaintext
1
buatUser
1 baris•8 chars
UTF-8•Spaces: 4
berubah,
PLAINTEXT Snippetplaintext
1
ReturnType
1 baris•10 chars
UTF-8•Spaces: 4
bakal selalu ngikutin bentuk return value yang sebenarnya, otomatis.

Bonus, Ngintip Cara Bikin Utility Type Sendiri

Semua utility types di atas sebenarnya cuma dibikin dari kombinasi fitur type level yang udah ada di TypeScript, kayak mapped types dan conditional types. Sekadar ngintip dikit, ini kira-kira gimana

PLAINTEXT Snippetplaintext
1
Partial
1 baris•7 chars
UTF-8•Spaces: 4
sebenarnya diimplementasiin di balik layar:

index.tstypescript
1
type PartialSendiri<T> = {
2
[K in keyof T]?: T[K];
3
};
3 baris•54 chars
UTF-8•Spaces: 4

PLAINTEXT Snippetplaintext
1
[K in keyof T]
1 baris•14 chars
UTF-8•Spaces: 4
di sini artinya "buat tiap key
PLAINTEXT Snippetplaintext
1
K
1 baris•1 chars
UTF-8•Spaces: 4
yang ada di
PLAINTEXT Snippetplaintext
1
T
1 baris•1 chars
UTF-8•Spaces: 4
", dan tanda
PLAINTEXT Snippetplaintext
1
?
1 baris•1 chars
UTF-8•Spaces: 4
bikin tiap key itu jadi opsional. Jangan khawatir kalau sintaks ini masih kerasa asing, karena ini justru topik utama yang bakal kita bahas mendalam di Series 2, Type-Level Programming. Series 1 ini sengaja fokus ke cara pakai utility types yang udah jadi, biar kamu punya bekal praktis dulu sebelum masuk ke bagian yang lebih dalam soal gimana semuanya itu dibikin.

Kesimpulan

Utility types itu ibarat perkakas siap pakai yang bikin hidup kamu jauh lebih gampang pas kerja sama tipe data di TypeScript.

PLAINTEXT Snippetplaintext
1
Partial
1 baris•7 chars
UTF-8•Spaces: 4
buat bikin semua properti opsional,
PLAINTEXT Snippetplaintext
1
Required
1 baris•8 chars
UTF-8•Spaces: 4
buat kebalikannya,
PLAINTEXT Snippetplaintext
1
Pick
1 baris•4 chars
UTF-8•Spaces: 4
buat ambil sebagian properti,
PLAINTEXT Snippetplaintext
1
Omit
1 baris•4 chars
UTF-8•Spaces: 4
buat buang sebagian properti,
PLAINTEXT Snippetplaintext
1
Record
1 baris•6 chars
UTF-8•Spaces: 4
buat bikin mapping objek yang type safe, dan
PLAINTEXT Snippetplaintext
1
ReturnType
1 baris•10 chars
UTF-8•Spaces: 4
buat nyolong tipe dari return value fungsi. Begitu kamu terbiasa pake keenamnya, kamu bakal jarang banget nulis interface duplikat cuma buat variasi kecil dari tipe yang udah ada.

Dan dengan ini, kita udah nyelesain seluruh Series 1, TypeScript Fundamentals. Dari alasan kenapa TypeScript worth dipelajari, bedanya

PLAINTEXT Snippetplaintext
1
any
1 baris•3 chars
UTF-8•Spaces: 4
,
PLAINTEXT Snippetplaintext
1
unknown
1 baris•7 chars
UTF-8•Spaces: 4
,
PLAINTEXT Snippetplaintext
1
never
1 baris•5 chars
UTF-8•Spaces: 4
, cara kerja type inference, union dan intersection type, generics, sampai utility types, kamu sekarang udah punya pondasi yang cukup kuat buat lanjut ke topik yang lebih dalam. Di Series 2 nanti, kita bakal masuk ke Type-Level Programming, mulai dari conditional types, template literal types, mapped types, sampai branded types, buat kamu yang pengen ngerti gimana sebenarnya "mesin" di balik semua utility types yang udah kamu pake selama ini.

Topik Terkait:JavascriptTypescript
Timur Dian Radha Sejati

Timur Dian Radha Sejati

Penulis & Lead Engineer

Software engineer dan konsultan sistem di SejatiDimedia. Berfokus pada perancangan arsitektur berkinerja tinggi, refactoring backend skala enterprise, hingga pengembangan aplikasi mobile, web modern dan integrasi AI.

Punya Masalah Arsitektur atau Ingin Membangun Sistem yang Benar?

Kami siap membantu mengaudit kode, me-refactor arsitektur yang lemot, atau membangun aplikasi bisnis Anda dengan standar enterprise sejak awal.

EKSPLORASI LANJUTAN

Artikel Rekayasa Terkait

Lihat Semua
Generics, dari Dasar sampai Constraint
Best Practices
5 menit baca

Generics, dari Dasar sampai Constraint

Generics sering dianggap topik yang menakutkan buat pemula, padahal konsepnya sederhana banget kalau dijelasin pake analogi yang pas. Artikel ini mulai dari masalah nyata yang diselesain generics, yaitu bikin fungsi atau komponen yang reusable tanpa kehilangan informasi tipe. Pembaca bakal diajak bangun pemahaman step by step, dari generic function sederhana, generic interface, sampai penggunaan `extends` buat batasin tipe apa aja yang boleh masuk, dan default type parameter biar generic lebih fleksibel. Semua dijelasin pake contoh kode dunia nyata kayak fungsi fetch data API dan komponen wrapper.

Baca Artikel
Union, Intersection, dan Discriminated Union, Cara Memodelkan Data yang Punya Banyak Kemungkinan Bentuk
Best Practices
5 menit baca

Union, Intersection, dan Discriminated Union, Cara Memodelkan Data yang Punya Banyak Kemungkinan Bentuk

Artikel ini fokus ke salah satu fitur paling kuat di TypeScript buat memodelkan data yang bentuknya bisa berubah-ubah. Dimulai dari union type dasar buat bilang "nilai ini bisa A atau B", lanjut ke intersection type buat gabungin beberapa tipe jadi satu, sampai discriminated union yang super berguna buat memodelkan state kayak loading, success, dan error di aplikasi nyata. Ada juga pembahasan gimana TypeScript otomatis ngelakuin narrowing berdasarkan properti pembeda, jadi kode kamu lebih aman tanpa perlu banyak pengecekan manual yang rawan salah.

Baca Artikel
Type Inference, Kapan TypeScript Udah Cukup Pinter dan Kapan Perlu Dibantu
Best Practices
5 menit baca

Type Inference, Kapan TypeScript Udah Cukup Pinter dan Kapan Perlu Dibantu

Banyak pemula yang kebiasaan nulis anotasi tipe di mana-mana padahal TypeScript sebenarnya udah bisa nebak sendiri. Artikel ini ngebahas gimana mekanisme type inference kerja di balik layar, kapan inference bekerja dengan baik, dan kapan justru bisa menyesatkan, misalnya di array kosong atau objek yang bentuknya berubah seiring waktu. Ada juga pembahasan soal contextual typing dan kapan sebaiknya tetap nulis anotasi eksplisit meski secara teknis gak wajib. Cocok buat kamu yang ngerasa kode TypeScript-nya kepanjangan gara-gara kebanyakan nulis tipe manual.

Baca Artikel