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:
function bungkus(nilai: any): any[] {
return [nilai];
}
const hasil = bungkus("halo");
hasil[0].toUpperCase(); // lolos cek, tapi tipe hasil adalah any: tidak amanDengan any, informasi tipe hilang total. Autocomplete mati, typo tidak ketahuan.
Solusi: Type Parameter
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
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
Thanyalah konvensi (singkatan dari Type). Untuk generic ganda, pakai nama deskriptif seperti<Kunci, Nilai>atau<TData, TError>agar terbaca. Hindarianysebagai "generic malas":function f(x: any)terlihat fleksibel tapi mematikan seluruh sistem tipe di sekitarnya.