Lompat ke konten Lompat ke sidebar Lompat ke footer

Widget HTML #1

Panduan Lengkap Typescript Generic: Kunci Menulis Kode yang Fleksibel dan Reusable

TypeScript Generic, Kode fleksibel TypeScript, Generics pada TypeScript

Kalau kita berbicara tentang TypeScript, salah satu fitur yang sering menjadi bahan pembicaraan adalah generics. Mungkin awalnya terdengar seperti konsep yang super teknis dan berat, tapi percayalah, generics itu seperti bumbu dapur dalam masakan kode kita. Tanpa generics, kode TypeScript kita tetap bisa jalan, tapi rasanya kurang "nendang". Nah, di artikel ini, kita akan membahas generics dengan gaya santai dan mendalam. Siap? Mari kita mulai!

Apa Itu Generic dalam TypeScript?

Generic adalah fitur di TypeScript yang memungkinkan kita membuat fungsi, kelas, atau interface yang bekerja dengan berbagai tipe data, tanpa harus mengorbankan tipe tersebut. Artinya, kita bisa membuat kode yang lebih fleksibel tetapi tetap aman dari kesalahan tipe.

Misalnya, bayangkan kita punya fungsi untuk mengembalikan elemen pertama dari array apa pun:

function getFirstElement(array: any[]): any {
  return array[0];
}

Fungsi di atas kelihatannya baik-baik saja, tapi ada satu masalah besar: tipe data hasilnya selalu any. Kalau kita berharap hasilnya berupa string, dan ternyata keluar angka, TypeScript tidak akan memperingatkan kita. Nah, di sinilah generics beraksi!

Dengan generics, kita bisa menulis fungsi yang "tahu" tipe datanya:

function getFirstElement<T>(array: T[]): T {
  return array[0];
}

Perhatikan bagian <T> di definisi fungsi. Huruf T di sini adalah placeholder untuk tipe data. Ketika kita memanggil fungsi ini, kita bisa menentukan tipe yang kita inginkan, atau membiarkan TypeScript menebaknya.

Mengapa Generic Penting?

Mungkin kita bertanya-tanya, "Kenapa harus repot-repot pakai generic? Bukannya pakai any lebih simpel?" Pertanyaan bagus! Berikut beberapa alasan kenapa generics itu penting:

  1. Keamanan Tipe (Type Safety): Dengan generics, kita mendapatkan validasi tipe di waktu kompilasi. Ini berarti lebih sedikit bug di produksi.
  2. Kode Reusable: Generics memungkinkan kita menulis kode yang fleksibel dan bisa digunakan kembali untuk berbagai tipe data.
  3. Dokumentasi Otomatis: Kode kita jadi lebih mudah dimengerti karena tipe data selalu eksplisit.

Bayangkan kita sedang bekerja dengan API yang menghasilkan berbagai tipe data. Daripada menulis fungsi terpisah untuk setiap tipe, kita bisa menulis satu fungsi dengan generic. Hemat waktu, kan?

Membuat Fungsi Generic

Mari kita mulai dengan dasar-dasar. Seperti yang sudah kita lihat sebelumnya, membuat fungsi generic cukup mudah. Berikut adalah beberapa contoh penggunaan fungsi generic:

Contoh 1: Mengembalikan Elemen Pertama

function getFirstElement<T>(array: T[]): T {
  return array[0];
}

const numbers = [1, 2, 3];
const firstNumber = getFirstElement(numbers); // Tipe: number

const strings = ['a', 'b', 'c'];
const firstString = getFirstElement(strings); // Tipe: string

Fungsi ini fleksibel, tapi tetap menjaga keamanan tipe. Kalau kita coba memberikan input yang bukan array, TypeScript akan langsung protes.

Contoh 2: Swap Dua Elemen

Misalkan kita ingin membuat fungsi untuk menukar dua elemen dalam array:

function swap<T>(array: T[], index1: number, index2: number): T[] {
  const temp = array[index1];
  array[index1] = array[index2];
  array[index2] = temp;
  return array;
}

const myArray = [1, 2, 3];
const swappedArray = swap(myArray, 0, 2); // Hasil: [3, 2, 1]

Fungsi ini akan bekerja dengan array apa pun, dari angka hingga objek kompleks.

Generic pada Kelas

Generics tidak hanya untuk fungsi, tapi juga bisa diterapkan pada kelas. Misalnya, kita ingin membuat kelas Stack (tumpukan) yang bisa menampung elemen dari tipe apa pun:

class Stack<T> {
  private items: T[] = [];

  push(item: T): void {
    this.items.push(item);
  }

  pop(): T | undefined {
    return this.items.pop();
  }

  peek(): T | undefined {
    return this.items[this.items.length - 1];
  }
}

const numberStack = new Stack<number>();
numberStack.push(42);
console.log(numberStack.peek()); // 42

const stringStack = new Stack<string>();
stringStack.push('hello');
console.log(stringStack.peek()); // 'hello'

Dengan menggunakan generic, kita bisa memastikan bahwa stack hanya menerima dan mengembalikan tipe data yang sesuai.

Generic pada Interface

Interface juga bisa menggunakan generic. Misalnya, kita ingin membuat interface untuk struktur data Pair (pasangan):

interface Pair<T, U> {
  first: T;
  second: U;
}

const numberStringPair: Pair<number, string> = {
  first: 1,
  second: 'satu',
};

const booleanArrayPair: Pair<boolean, number[]> = {
  first: true,
  second: [1, 2, 3],
};

Dengan pendekatan ini, kita bisa membuat interface yang fleksibel tanpa kehilangan keamanan tipe.

Batasan Tipe pada Generic

Kadang-kadang, kita ingin membatasi tipe data yang bisa digunakan pada generic. Misalnya, kita ingin memastikan bahwa sebuah parameter selalu memiliki properti tertentu:

interface Lengthwise {
  length: number;
}

function logLength<T extends Lengthwise>(item: T): void {
  console.log(item.length);
}

logLength({ length: 10, name: 'Item' }); // Oke
logLength(123); // Error: number tidak memiliki properti 'length'

Kesimpulan

Generics adalah salah satu fitur terbaik TypeScript untuk menulis kode yang fleksibel, reusable, dan aman. Dengan memahami cara kerja dan penerapannya, kita bisa membuat aplikasi yang lebih modular dan bebas bug.

Bagaimana? Masih takut sama generics? Kalau kita sudah sampai di sini, generics seharusnya lebih terasa seperti teman baik daripada momok menakutkan. Jangan lupa terus berlatih, dan siapa tahu, suatu hari nanti kita bisa membuat library TypeScript kita sendiri dengan bantuan generics!

Selamat ngoding!

1 komentar untuk "Panduan Lengkap Typescript Generic: Kunci Menulis Kode yang Fleksibel dan Reusable"