interfaceextendsoopPemula3 mnt baca

Interface Extends

Mewarisi dan menggabungkan interface dengan extends: DRY untuk tipe object.

Analogi: Resep Warisan Keluarga

Bayangin resep kue dasar keluarga: tepung, gula, telur. Anaknya bikin varian cokelat dengan menambah bubuk kakao, cucunya bikin varian keju dengan menambah parutan keju. Tidak ada yang nulis ulang resep dasar dari nol, semua "mewarisi" lalu menambahkan.

extends di interface bekerja persis seperti itu. Interface anak mewarisi semua properti interface induk, lalu boleh menambah properti sendiri.

Kenapa extends Ada?

Tanpa extends, hierarki tipe harus ditulis dengan copy-paste:

typescript
interface Pengguna {
  id: string;
  nama: string;
  email: string;
}

interface Admin {
  id: string;      // salinan...
  nama: string;    // salinan...
  email: string;   // salinan...
  levelAkses: number;
}

Masalahnya klasik: besok Pengguna tambah properti avatar, kamu harus ingat mengupdate Admin, Pelanggan, Moderator, dan semua turunannya satu per satu. Satu saja kelupaan, kontrak datanya diam-diam tidak sinkron.

Dengan extends, hubungan ditulis sekali dan selalu sinkron:

typescript
interface Pengguna {
  id: string;
  nama: string;
  email: string;
}

interface Admin extends Pengguna {
  levelAkses: number;
}

const a: Admin = { id: "A1", nama: "Budi", email: "[email protected]", levelAkses: 3 };
// wajib punya semua properti Pengguna + levelAkses

Ini DRY (Don't Repeat Yourself) untuk tipe: satu sumber kebenaran untuk bentuk dasar.

Contoh Error Compiler yang Nyata

Warisan bukan berarti bebas. Properti yang dideklarasikan ulang harus kompatibel dengan induknya:

typescript
interface Hewan {
  nama: string;
  kaki: number;
}

interface Kucing extends Hewan {
  kaki: string; // SALAH: induk bilang number
}
// Error: Interface 'Kucing' incorrectly extends interface 'Hewan'.
//   Types of property 'kaki' are incompatible.
//   Type 'string' is not assignable to type 'number'.

Error ini sebenarnya penjaga yang baik: dia mencegah anak "mengkhianati" kontrak induknya. Kalau Hewan menjanjikan kaki berupa number, semua kode yang menerima Hewan berhak mengasumsikan itu.

Satu interface juga bisa extends banyak interface sekaligus:

typescript
interface Terbang { kecepatanTerbang: number; }
interface Berenang { kedalamanMaks: number; }

interface Bebek extends Terbang, Berenang {
  nama: string;
}

const d: Bebek = { nama: "Donal", kecepatanTerbang: 40, kedalamanMaks: 5 };

Kapan extends Berguna di Project Nyata

  • Hierarki domain: Pengguna sebagai dasar, lalu Admin, Pelanggan, Kurir menambah propertinya masing-masing.
  • API versioning: response v2 extends v1 lalu tambah field baru. Kode lama yang memakai v1 tetap aman.
  • Props komponen: ButtonProps extends BaseProps menambah onClick di atas properti dasar seperti className dan disabled.

Catatan teknis: extends hanya bisa dipakai oleh interface, dan hanya ke tipe berbentuk object. Untuk type alias, penggabungan dilakukan dengan intersection (&), dibahas di modul intersection-type. Perilakunya mirip, tapi extends memberi pesan error yang lebih jelas saat ada konflik properti.

Kesalahan Umum Pemula

1. Copy-paste properti induk alih-alih extends

SALAH:

typescript
interface Admin {
  id: string; nama: string; email: string; // duplikat dari Pengguna
  levelAkses: number;
}

BENAR:

typescript
interface Admin extends Pengguna {
  levelAkses: number;
}

2. Mendeklarasikan ulang properti dengan tipe beda

SALAH:

typescript
interface Induk { kode: number; }
interface Anak extends Induk { kode: string; } // Error: incorrectly extends

BENAR:

typescript
interface Induk { kode: number; }
interface Anak extends Induk { kode: number; keterangan: string } // OK
// atau ubah tipenya di induk sekalian kalau memang salah di sana

3. extends ke union type

SALAH:

typescript
type A_atau_B = { a: string } | { b: number };
interface C extends A_atau_B {}
// Error: An interface can only extend an object type or intersection of
//        object types with statically known members.

BENAR:

typescript
type C = A_atau_B & { c: boolean }; // intersection untuk type alias

4. Lupa properti warisan saat bikin object

SALAH:

typescript
interface Kucing extends Hewan { sukaTidur: boolean; }
const k: Kucing = { sukaTidur: true };
// Error: Property 'nama' is missing... (warisan dari Hewan wajib diisi)

BENAR:

typescript
const k: Kucing = { nama: "Mochi", sukaTidur: true };

Tantangan

Hierarki kendaraan

Buat interface Kendaraan (merk: string, tahun: number), lalu Mobil extends Kendaraan tambah jumlahPintu: number, dan Motor extends Kendaraan tambah adaGigi: boolean. Buat satu object tiap tipe dan pastikan compiler menerima keduanya.

typescript
interface Kendaraan {
  merk: string;
  tahun: number;
}

// tulis Mobil dan Motor di sini

const avanza: Mobil = { merk: "Toyota", tahun: 2022, jumlahPintu: 4 };
const beat: Motor = { merk: "Honda", tahun: 2023, adaGigi: false };