genericfungsitipeMenengah4 mnt baca

Generic Dasar

Fungsi dan tipe yang fleksibel untuk banyak tipe data tanpa kehilangan informasi tipe.

Masalah yang Diselesaikan Generic

Kamu butuh fungsi bungkus yang menerima nilai apa pun dan mengembalikan array berisi nilai itu. Tanpa generic, pilihannya buruk:

typescript
function bungkus(nilai: any): any[] {
  return [nilai];
}

const hasil = bungkus("halo");
hasil[0].toUpperCase(); // lolos cek, tapi tipe hasil adalah any: tidak aman

Dengan any, informasi tipe hilang total. Autocomplete mati, typo tidak ketahuan.

Solusi: Type Parameter

typescript
function bungkus<T>(nilai: T): T[] {
  return [nilai];
}

const a = bungkus("halo"); // T = string, a bertipe string[]
const b = bungkus(123);    // T = number, b bertipe number[]

a[0].toUpperCase(); // ok, a[0] pasti string
b[0].toUpperCase(); // Error: Property 'toUpperCase' does not exist on type 'number'

T adalah placeholder tipe yang diisi saat fungsi dipanggil. Satu definisi fungsi, bekerja untuk semua tipe, dan informasi tipe tetap terjaga penuh.

Generic pada Tipe dan Interface

typescript
interface ResponsAPI<T> {
  sukses: boolean;
  data: T;
  pesan?: string;
}

const userRes: ResponsAPI<{ nama: string }> = {
  sukses: true,
  data: { nama: "Ana" },
};

Pola ResponsAPI<T> dipakai di hampir semua codebase yang bicara dengan backend: bungkusnya sama, isinya beda-beda.

Inference Bekerja Otomatis

Kamu jarang perlu menulis bungkus<string>("halo") secara eksplisit. TypeScript mengisi T dari argumen. Tulis eksplisit hanya saat inference gagal menebak atau kamu ingin memaksa tipe yang lebih spesifik.

Catatan teknis: Nama T hanyalah konvensi (singkatan dari Type). Untuk generic ganda, pakai nama deskriptif seperti <Kunci, Nilai> atau <TData, TError> agar terbaca. Hindari any sebagai "generic malas": function f(x: any) terlihat fleksibel tapi mematikan seluruh sistem tipe di sekitarnya.