Lewati ke konten utama
menjadi.dev
Chapter 18.4 JavaScript Menengah

Interface vs Type Alias: Kapan Pakai Mana?

Pahami dua cara mendefinisikan tipe dan trade-off masing-masing

Tujuan Pembelajaran

  • Memahami perbedaan interface dan type alias
  • Bisa memilih yang tepat untuk use case
  • Mengerti declaration merging dan intersection

Analogi

Diagram

      Interface:
interface User { name: string; }
interface User { age: number; }  // Merge!
// User sekarang punya name + age

Type:
type User = { name: string; }
type User = { age: number; }   // Error! Duplicate
    

Interface bisa merge (declaration merging), Type lebih fleksibel untuk union dan tuple

Penjelasan Konsep

Di TypeScript ada dua cara mendefinisikan tipe custom: interface dan type alias.

Keduanya sering dipakai interchangeably, tapi punya perbedaan penting yang mempengaruhi kapan harus pakai mana.

Interface

Interface adalah cara mendefinisikan shape object.

Bisa di-extend, di-implement oleh class, dan punya fitur declaration merging.

interface User {
  id: number;
  name: string;
}

// Declaration merging — interface dengan nama sama digabungkan
interface User {
  email: string;
}

// User sekarang punya: id, name, email
const u: User = { id: 1, name: 'Budi', email: 'a@b.com' };

Declaration merging berguna saat kamu perlu menambahkan properti ke interface yang sudah ada — misalnya menambahkan properti ke Window atau Express Request object.

Type Alias

Type alias lebih fleksibel — bisa mendefinisikan union, tuple, primitive alias, dan mapped types:

type ID = string | number;
type Point = [number,

Number];
type Status = 'active' | 'inactive' | 'pending';

// Union yang tidak bisa dibuat dengan interface
type Response = { success: true; data: User } | { success: false; error: string };

Kapan Pakai Mana?

Pakai Interface kalau

  • Mendefinisikan shape object
  • Perlu extends / implements
  • Mungkin perlu declaration merging
  • API public yang mungkin di-extend user

Pakai Type kalau

  • Butuh union type
  • Butuh tuple type
  • Type sederhana (alias)
  • Mapped types atau conditional types
  • Tidak perlu declaration merging

Rule of Thumb dari TypeScript Team

Mulai dengan interface.

Pindah ke type kalau butuh fitur yang hanya type punya (union).

Ini konsisten dengan codebase TypeScript itu sendiri.

Intersection Type

Gabungkan dua tipe dengan &:

type WithTimestamp = { createdAt: Date; updatedAt: Date };
type UserWithTimestamp = User & WithTimestamp;

Intersection sering dipakai untuk menambahkan properti ke tipe yang sudah ada tanpa mengubah tipe asli.

Inti yang Perlu Dipahami

Bagian ini berfokus pada memahami perbedaan interface dan type alias., bisa memilih yang tepat untuk use case., dan mengerti declaration merging dan intersection. Jangan terburu-buru menghafal istilahnya. Lebih penting untuk memahami peran setiap konsep dan kapan konsep itu muncul dalam pekerjaan web development.

Saat membaca Interface vs Type Alias, gunakan tujuan belajar sebagai penanda arah. Kalau kamu sudah bisa menjelaskan tujuan itu dengan kata-katamu sendiri, berarti fondasinya mulai terbentuk.

Cara Membayangkannya

Interface bisa merge (declaration merging), Type lebih fleksibel untuk union dan tuple. Analogi ini dipakai supaya konsep teknis tidak terasa melayang. Hubungkan setiap istilah dengan perannya: siapa yang meminta, siapa yang memproses, data apa yang berpindah, dan hasil apa yang diharapkan.

Kalau analoginya sudah terasa masuk akal, barulah lihat istilah teknisnya. Cara ini membuat materi lebih mudah dipahami daripada langsung menghafal definisi.

Saat Melihat Contoh Kode

Contoh kode pada chapter ini memakai bahasa typescript. Bacalah contoh kode sebagai ilustrasi alur, bukan sebagai bagian yang harus langsung dihafal. Entity & Auditable & SoftDeletable = compose behavior via intersection. ApiResponse<T> menggunakan union untuk representasi response yang bisa sukses atau error.

Perhatikan nama fungsi, urutan langkah, dan data yang berpindah. Biasanya tiga hal itu sudah cukup untuk memahami hubungan antara teori dan praktik.

Konteks dalam Perjalanan Belajar

Setiap konsep di platform ini dipilih karena dipakai di industri. Fokus pada pemahaman, bukan hafalan.

Kamu sudah di bagian lanjutan. Mulai pikirkan bagaimana konsep ini dipakai di dunia kerja — bukan hanya untuk belajar, tapi untuk membangun produk nyata.

Gunakan pertanyaan reflektif dan prompt AI di akhir chapter sebagai latihan aktif. Membaca saja tidak cukup — kamu perlu menjelaskan ulang dengan kata-katamu sendiri.

Contoh Kode

typescript
// Pattern: Base interface + feature interfaces
interface Entity {
  id: number;
  createdAt: Date;
}

interface Auditable {
  createdBy: string;
  updatedBy: string;
  updatedAt: Date;
}

interface SoftDeletable {
  deletedAt: Date | null;
  isDeleted: boolean;
}

// Compose dengan intersection
type Product = Entity & Auditable & SoftDeletable & {
  name: string;
  price: number;
  stock: number;
};

// API Response pattern dengan type
type ApiSuccess<T> = {
  success: true;
  data: T;
  meta?: { page: number; total: number };
};

type ApiError = {
  success: false;
  error: string;
  code: string;
};

type ApiResponse<T> = ApiSuccess<T> | ApiError;

// Type guard untuk response
function isSuccess<T>(res: ApiResponse<T>): res is ApiSuccess<T> {
  return res.success === true;
}

const res: ApiResponse<User> = await fetchApi('/user/1');
if (isSuccess(res)) {
  console.log(res.data.name);  // Tipe-safe!
} else {
  console.error(res.error);    // Tipe-safe!
}

Penjelasan Kode

Entity & Auditable & SoftDeletable = compose behavior via intersection. ApiResponse<T> menggunakan union untuk representasi response yang bisa sukses atau error.

Prompt AI

Refactor interface User yang sudah kamu buat: pisahkan Entity (id, timestamps), Auditable (who changed), dan Profile (name, email). Compose dengan intersection.

Pertanyaan Reflektif

Di codebase TypeScript populer (React, Vite, etc), cari 5 contoh interface dan 5 contoh type alias. Apakah mereka mengikuti rule of thumb?