Berikan struktur pada datamu! Pelajari cara mendefinisikan bentuk objek di TypeScript menggunakan anotasi tipe inline, Interface, dan Type Aliases untuk kode yang lebih terorganisir dan type-safe.
17m bacaanKuis WajibMicro Badge Lesson
Ngasih "Cetakan" ke Data: Objek, Interface, & Type Aliases di TypeScript!
Udah bisa ngasih tipe ke variabel dasar dan parameter fungsi? Keren! Sekarang, gimana kalau data kita itu lebih kompleks, misalnya data seorang pengguna yang punya nama, umur, email, dan alamat? Atau data produk yang punya ID, nama, harga, dan deskripsi?
Di JavaScript, kita biasa pake objek literal ({}) buat ngewakilin data terstruktur kayak gitu. Nah, di TypeScript, kita bisa (dan sangat disarankan buat) ngasih "cetakan" atau "bentuk" (shape) ke objek-objek ini biar lebih jelas properti apa aja yang seharusnya ada dan apa tipe datanya.
Ada beberapa cara buat ngedefinisiin bentuk objek di TypeScript:
Anotasi Tipe Inline untuk Objek
interface (Cara yang paling umum dan idiomatik buat objek)
type Aliases (Lebih fleksibel, bisa buat tipe apa aja, termasuk objek)
Yuk, kita bedah satu-satu!
1. Anotasi Tipe Inline untuk Objek
Ini cara paling langsung buat ngasih tau tipe sebuah objek. Kamu definisiin bentuknya langsung pas deklarasi variabel atau parameter.
typescript
let pengguna: { nama: string; umur: number; aktif: boolean; };pengguna = { nama: "Budi Santoso", umur: 30, aktif: true};// pengguna = { nama: "Siti", umur: "dua puluh" }; // ERROR! Umur harus number// pengguna = { nama: "Ani" }; // ERROR! Properti 'umur' dan 'aktif' hilangfunction cetakInfoProduk(produk: { id: number; nama: string; harga?: number }) { // harga opsional console.log(`Produk: ${produk.nama} (ID: ${produk.id})`); if (produk.harga) { console.log(`Harga: Rp ${produk.harga}`); }}cetakInfoProduk({ id: 101, nama: "Laptop Keren", harga: 15000000 });cetakInfoProduk({ id: 102, nama: "Mouse Gaming" }); // Oke, harga opsional
Cara ini oke buat objek simpel yang cuma dipake sekali atau dua kali. Tapi, kalau bentuk objek yang sama mau kamu pake di banyak tempat, nulis ulang anotasinya terus-terusan jadi gak efisien. Nah, di situlah interface dan type aliases masuk.
2. interface: Bikin "Kontrak Bentuk" Objek yang Reusable!
interface di TypeScript adalah cara yang powerful buat ngasih nama ke sebuah struktur objek. Dia kayak "kontrak" atau "blueprint" yang ngasih tau properti apa aja yang harus (atau boleh) ada di objek, beserta tipe datanya.
Sintaks Dasar interface:
typescript
interface NamaInterfaceKamu { namaProperti1: TipeData1; namaProperti2: TipeData2; propertiOpsional?: TipeData3; // Tanda tanya (?) buat properti opsional readonly propertiReadOnly: TipeData4; // Cuma bisa dibaca, gak bisa diubah setelah inisialisasi objek metodeLagi?(param: Tipe): TipeReturn; // Metode juga bisa didefinisikan}
Contoh Penggunaan interface:
typescript
interface Pengguna { id: number; nama: string; email: string; alamat?: string; // Alamat itu opsional readonly tanggalDaftar: Date; // Gak bisa diubah setelah diset sapa(): string; // Metode yang harus ada dan mengembalikan string}let pengguna1: Pengguna = { id: 1, nama: "Citra Lestari", email: "citra@email.com", tanggalDaftar: new Date(), sapa: function() { // atau sapa() { return `Halo, ${this.nama}`; } return `Halo, nama saya ${this.nama}`; }};// pengguna1.tanggalDaftar = new Date(); // ERROR! tanggalDaftar itu readonly// pengguna1.id = 2; // ERROR jika id didefinisikan sbg readonly interface Pengguna { readonly id: number; ... }console.log(pengguna1.sapa()); // Output: Halo, nama saya Citra Lestarilet pengguna2: Pengguna = { id: 2, nama: "Andi Wijaya", email: "andi@email.com", alamat: "Jl. Mawar No. 10", // Ngasih nilai ke properti opsional tanggalDaftar: new Date(), sapa: () => `Hi, I'm Andi` // Implementasi metode bisa beda};
Kelebihan interface:
Reusable: Kamu bisa pake nama interface (Pengguna) di banyak tempat sebagai tipe.
Jelas dan Deskriptif: Langsung keliatan "bentuk" data yang diharapkan.
Bisa di-extend (Declaration Merging & Inheritance):
Kamu bisa nambahin properti baru ke interface yang udah ada dengan ngedeklarasiin interface dengan nama yang sama lagi (Declaration Merging).
Satu interface bisa "mewarisi" properti dari interface lain pake keyword extends.
typescript
interface Karyawan extends Pengguna { // Karyawan mewarisi semua properti Pengguna jabatan: string; gaji: number;}let karyawan1: Karyawan = { id: 3, nama: "Dewi Anggraini", email: "dewi@email.com", tanggalDaftar: new Date(), sapa: () => `Hello, ${karyawan1.nama}`, jabatan: "Software Engineer", gaji: 20000000};
3. type Aliases: Ngasih Nama ke Tipe Apa Aja (Termasuk Bentuk Objek)
type Aliases ngasih kita cara buat ngasih nama alias ke tipe apa pun. Ini bisa tipe primitif, union type, intersection type, tuple, function type, dan pastinya bentuk objek juga.
Sintaks Dasar type Alias buat Objek:
typescript
type NamaTypeAliasKamu = { namaProperti1: TipeData1; namaProperti2: TipeData2; // ... mirip kayak daleman interface};
Contoh Penggunaan type Alias buat Objek:
typescript
type TitikKoordinat = { x: number; y: number; label?: string;};let titikA: TitikKoordinat = { x: 10, y: 20 };let titikB: TitikKoordinat = { x: 5, y: 15, label: "Titik B" };// Type alias juga bisa buat tipe lain:type ID = string | number; // Union typetype FungsiCallback = (data: any) => void; // Function typelet idPengguna: ID = "user-123";idPengguna = 456; // Okeconst prosesData: FungsiCallback = (hasil) => { console.log("Data diproses:", hasil);};
interface vs. type Aliases buat Objek: Kapan Pake yang Mana?
Buat ngedefinisiin "bentuk" objek, interface dan type aliases itu seringkali bisa dipake secara bergantian dan punya banyak kemiripan. Tapi, ada beberapa perbedaan kunci dan konvensi:
Declaration Merging: interface mendukung declaration merging, type aliases enggak. Artinya, kalau kamu definisiin dua interface dengan nama yang sama, TypeScript bakal ngegabungin propertinya. Ini kadang berguna buat nge-extend interface dari library pihak ketiga.
typescript
interface Mobil { merek: string; }interface Mobil { tahun: number; } // Ini bakal digabung jadi Mobil { merek: string; tahun: number; }// type DataMobil = { merek: string; };// type DataMobil = { tahun: number; }; // ERROR! Gak bisa redeclare type alias DataMobil.
Extending/Implementing:
interface bisa extends interface lain (atau class). Class juga bisa implements interface (buat mastiin class itu punya properti/metode tertentu).
type aliases bisa ngelakuin hal mirip inheritance pake intersection types (&).
Fleksibilitas type: type aliases lebih fleksibel karena dia bisa ngasih nama ke tipe apa pun, gak cuma bentuk objek (misal, union type, tuple, tipe primitif). interface itu khusus buat ngedefinisiin bentuk objek (atau class).
Saran Umum dari Komunitas (Gak Aturan Baku):
Pake interface kalau kamu lagi ngedefinisiin "bentuk" dari sebuah objek atau "kontrak" buat sebuah class. Karena lebih jelas tujuannya buat objek dan dukung declaration merging.
Pake type alias kalau kamu mau ngasih nama ke union type, intersection type, tuple, atau tipe fungsi, atau kalau kamu butuh fitur yang cuma ada di type (kayak mapped types, conditional types - ini udah advance).
Tapi, buat kasus objek simpel, dua-duanya seringkali bisa dipake. Yang penting konsisten di proyekmu.
Properti Opsional (?) dan Read-only (readonly)
Kita udah singgung sedikit di atas, tapi ini penting:
Properti Opsional (?): Tambahin tanda tanya ? setelah nama properti dan sebelum titik dua tipe datanya di interface atau type objek. Ini artinya properti itu gak wajib ada pas objeknya dibikin. Kalau diakses dan gak ada, nilainya undefined.
typescript
interface Produk { nama: string; harga: number; deskripsi?: string; // deskripsi ini opsional}let buku: Produk = { nama: "Buku TypeScript", harga: 150000 }; // Oke, deskripsi gak ada
Properti Read-only (readonly): Tambahin keyword readonly sebelum nama properti. Ini artinya nilai properti itu cuma bisa diset pas objeknya pertama kali dibikin. Setelah itu, gak bisa diubah lagi nilainya.
typescript
interface User { readonly id: number; username: string;}let userBaru: User = { id: 1, username: "budi_ts" };// userBaru.id = 2; // ERROR! Properti 'id' itu readonly.
Dengan interface dan type aliases, kamu bisa bikin "cetakan" yang jelas buat struktur data objekmu. Ini bikin kode TypeScript-mu jadi lebih aman, gampang dipahami, dan enak banget buat di-maintain, apalagi pas datanya makin kompleks atau kamu kerja bareng tim.
Biasain diri buat ngedefinisiin bentuk datamu pake interface atau type sebelum kamu mulai ngolah data itu. Ini investasi kecil di awal yang bakal ngasih banyak manfaat di belakang!
Checkpoint KuisTarget: 70%
Kuis Objek, Interface, & Type Aliases di TypeScript
Kuis ini wajib untuk sertifikat. Kamu tetap bisa lanjut ke pelajaran berikutnya dan mengerjakannya nanti.