Objek, Interface, & Type Aliases TS
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.
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)typeAliases (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.
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' hilang
function 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 opsionalCara 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:
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 Lestari
let 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
typeAlias buat Objek:typescript
type NamaTypeAliasKamu = { namaProperti1: TipeData1; namaProperti2: TipeData2; // ... mirip kayak daleman interface };
Contoh Penggunaan type Alias buat Objek:
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 type
type FungsiCallback = (data: any) => void; // Function type
let idPengguna: ID = "user-123";
idPengguna = 456; // Oke
const 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:
interfacemendukung declaration merging,typealiases enggak. Artinya, kalau kamu definisiin duainterfacedengan 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:
interfacebisaextendsinterface lain (atau class). Class juga bisaimplementsinterface (buat mastiin class itu punya properti/metode tertentu).typealiases bisa ngelakuin hal mirip inheritance pake intersection types (&).typescript
type KendaraanDasar = { roda: number; }; type MobilTipe = KendaraanDasar & { pintu: number; merek: string; }; // Pake intersection
-
Fleksibilitas
type:typealiases lebih fleksibel karena dia bisa ngasih nama ke tipe apa pun, gak cuma bentuk objek (misal, union type, tuple, tipe primitif).interfaceitu khusus buat ngedefinisiin bentuk objek (atau class).
Saran Umum dari Komunitas (Gak Aturan Baku):
- Pake
interfacekalau kamu lagi ngedefinisiin "bentuk" dari sebuah objek atau "kontrak" buat sebuah class. Karena lebih jelas tujuannya buat objek dan dukung declaration merging. - Pake
typealias kalau kamu mau ngasih nama ke union type, intersection type, tuple, atau tipe fungsi, atau kalau kamu butuh fitur yang cuma ada ditype(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 diinterfaceatautypeobjek. Ini artinya properti itu gak wajib ada pas objeknya dibikin. Kalau diakses dan gak ada, nilainyaundefined.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 keywordreadonlysebelum 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. userBaru.username = "budi_keren"; // Oke, username bisa diubah.readonlyini bagus buat properti yang emang seharusnya gak pernah berubah, kayak ID unik.
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!
Uji Pemahamanmu!
Memeriksa status login...