TypeScript Generics: Dari Bingung Sampai Paham dalam Satu Artikel
Generics adalah fitur TypeScript yang paling banyak dihindari pemula. Padahal ini kunci untuk menulis kode yang benar-benar type-safe dan reusable.
Kenapa Generics Penting?
Tanpa generics, kamu terpaksa memilih antara kode yang reusable (tapi kehilangan type safety) atau kode yang type-safe (tapi tidak reusable). Generics memberikan keduanya.
Masalah yang Dipecahkan Generics
// Tanpa generics — terpaksa pakai any
function getFirst(arr: any[]): any {
return arr[0];
}
// TypeScript tidak tahu return type-nya apa
const first = getFirst([1, 2, 3]); // type: any ?
Solusi dengan Generics
function getFirst<T>(arr: T[]): T {
return arr[0];
}
const first = getFirst([1, 2, 3]); // type: number ✅
const word = getFirst(["a", "b"]); // type: string ✅
TypeScript menyimpulkan tipe T dari argumen yang kamu masukkan — kamu tidak perlu menulisnya secara eksplisit.
Generic dengan Constraint
interface HasId {
id: number;
}
function findById<T extends HasId>(items: T[], id: number): T | undefined {
return items.find(item => item.id === id);
}
// Hanya bisa dipanggil dengan array objek yang punya property id
Generic di Interface dan Type
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
type UserResponse = ApiResponse<User>;
type PostsResponse = ApiResponse<Post[]>;
Contoh Real: Custom Hook React
function useFetch<T>(url: string): { data: T | null; loading: boolean; error: string | null } {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
// ... fetch logic
return { data, loading, error };
}
// Pemakaian — type-safe sepenuhnya
const { data } = useFetch<User[]>("/api/users");
Kesimpulan
Generics bukan fitur "advanced" yang hanya dipakai library author. Begitu kamu mulai melihat pattern <T> sebagai "tipe yang ditentukan nanti", semuanya mulai masuk akal.