Generik dalam TypeScript

Generik dalam TypeScript

Artikel ini menjelaskan tentang generik dalam TypeScript.

YouTube Video

Generik dalam TypeScript

Generik dalam TypeScript adalah sebuah fitur yang memungkinkan Anda untuk mendefinisikan fungsi, kelas, dan antarmuka yang dapat digunakan kembali dan aman secara tipe dengan memparameterkan tipe. Menggunakan generik memungkinkan Anda untuk menulis kode yang tidak bergantung pada tipe spesifik, sehingga memungkinkan Anda melakukan operasi yang sama pada berbagai tipe.

Dasar-dasar Generik

Generik berfungsi seperti templat yang menerima tipe sebagai argumen, memungkinkan fungsi dan kelas untuk menangani tipe yang berbeda.

Fungsi Generik

Berikut adalah contoh fungsi dengan tipe argumen yang ditentukan menggunakan generik.

1function identity<T>(value: T): T {
2    return value;
3}
4
5console.log(identity<number>(42));       // 42
6console.log(identity<string>("Hello"));  // Hello
  • T adalah argumen tipe generik yang merepresentasikan tipe dari argumen fungsi dan nilai kembalian. Tipe sebenarnya ditentukan ketika fungsi dipanggil.
  • Dengan secara eksplisit menentukan <number> atau <string>, Anda menentukan tipenya.

Tipe generik bekerja tanpa spesifikasi eksplisit karena TypeScript melakukan inferensi tipe.

1function identity<T>(value: T): T {
2    return value;
3}
4
5console.log(identity(42));       // 42
6console.log(identity("Hello"));  // Hello

Keterbatasan pada Generik

Dengan memberikan batasan pada generik, Anda dapat membatasi mereka hanya menerima tipe tertentu saja.

1function loggingIdentity<T extends { length: number }>(arg: T): T {
2    console.log(arg.length);
3    return arg;
4}
5
6loggingIdentity("Hello");  // 5
7loggingIdentity([1, 2, 3]);  // 3
8
9// loggingIdentity(42);  // Error: number does not have a length property.
  • Menentukan T extends { length: number } menunjukkan bahwa T harus berupa tipe yang memiliki properti length. Oleh karena itu, tipe tanpa properti length tidak akan diterima.

Kelas Generik

Kelas juga dapat didefinisikan menggunakan generik. Kelas generik menawarkan tipe yang fleksibel untuk properti dan metode.

 1class Box<T> {
 2    private _value: T;
 3
 4    constructor(value: T) {
 5        this._value = value;
 6    }
 7
 8    public getValue(): T {
 9        return this._value;
10    }
11
12    public setValue(value: T): void {
13        this._value = value;
14    }
15}
16
17const numberBox = new Box<number>(100);
18console.log(numberBox.getValue());  // 100
19
20const stringBox = new Box<string>("Hello");
21console.log(stringBox.getValue());  // Hello
  • Box<T> mendeklarasikan tipe T yang digunakan dalam kelas sebagai generik. Ini memungkinkan kelas yang sama untuk digunakan kembali pada tipe yang berbeda.

Antarmuka Generik

Generik juga dapat digunakan dengan antarmuka.

 1interface Pair<T, U> {
 2    first: T;
 3    second: U;
 4}
 5
 6const numberStringPair: Pair<number, string> = { first: 1, second: "One" };
 7console.log(numberStringPair);  // { first: 1, second: 'One' }
 8
 9const booleanArrayPair: Pair<boolean, number[]> = { first: true, second: [1, 2, 3] };
10console.log(booleanArrayPair);  // { first: true, second: [ 1, 2, 3 ] }
  • Dengan menentukan dua tipe generik menggunakan Pair<T, U>, Anda dapat mendefinisikan sebuah objek dengan kombinasi tipe yang berbeda.

Argumen Tipe Bawaan

Anda juga dapat menentukan tipe bawaan untuk argumen tipe generik.

1function createArray<T = string>(length: number, value: T): T[] {
2    return Array(length).fill(value);
3}
4
5console.log(createArray(3, "a"));   // ['a', 'a', 'a']
6console.log(createArray(3, 100));   // [100, 100, 100]
  • Kami menetapkan argumen tipe bawaan ke string dengan <T = string>. Jika tidak ada tipe yang ditentukan secara eksplisit, T akan menjadi tipe string.

Alias Tipe Generik

Generik juga dapat digunakan sebagai alias tipe (type).

 1type Result<T> = {
 2    success: boolean;
 3    data: T;
 4};
 5
 6const successResult: Result<number> = { success: true, data: 42 };
 7const errorResult: Result<string> = { success: false, data: "Error occurred" };
 8
 9console.log(successResult);  // { success: true, data: 42 }
10console.log(errorResult);    // { success: false, data: 'Error occurred' }
  • Result<T> mewakili objek hasil yang berisi data dengan tipe T. Dengan cara ini, Anda dapat membuat alias tipe yang fleksibel menggunakan generik.

Beberapa Tipe Generik

Dengan menggunakan beberapa tipe generik, Anda dapat mendefinisikan fungsi dan kelas yang lebih serbaguna.

1function merge<T, U>(obj1: T, obj2: U): T & U {
2    return { ...obj1, ...obj2 };
3}
4
5const person = { name: "Alice" };
6const job = { title: "Engineer" };
7
8const merged = merge(person, job);
9console.log(merged);  // { name: 'Alice', title: 'Engineer' }
  • Fungsi merge menerima dua tipe berbeda, T dan U, dan menggabungkannya untuk mengembalikan objek baru.

Ringkasan

  • Generik memungkinkan kode dapat digunakan kembali dan aman tipe dengan memperlakukan tipe sebagai parameter.
  • Dengan menggunakan generik dalam fungsi, kelas, dan antarmuka, Anda dapat menulis logika fleksibel yang menangani berbagai jenis tipe.
  • Dengan menambahkan batasan pada argumen tipe atau menetapkan argumen tipe bawaan, Anda dapat mengontrol cakupan generik.

Dengan menggunakan generik, Anda dapat menulis kode yang tidak bergantung pada tipe, umum, dan memanfaatkan sistem tipe TypeScript yang kuat secara maksimal.

Anda dapat mengikuti artikel di atas menggunakan Visual Studio Code di saluran YouTube kami. Silakan periksa juga saluran YouTube kami.

YouTube Video