Generik dalam TypeScript

Generik dalam TypeScript

Artikel ini menerangkan tentang generik dalam TypeScript.

YouTube Video

Generik dalam TypeScript

Generik dalam TypeScript adalah satu ciri yang membolehkan anda mendefinisikan fungsi, kelas, dan antara muka yang boleh digunakan semula dan selamat jenis dengan memparameterkan jenis. Menggunakan generik membolehkan anda menulis kod yang tidak bergantung kepada jenis tertentu, membolehkan anda melakukan operasi yang sama pada pelbagai jenis.

Asas Generik

Generik bertindak seperti templat yang menerima jenis sebagai argumen, membolehkan fungsi dan kelas mengendalikan pelbagai jenis.

Fungsi Generik

Berikut adalah contoh fungsi dengan jenis argumennya 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 jenis generik yang mewakili jenis argumen fungsi dan nilai yang dikembalikan. Jenis sebenar ditentukan apabila fungsi dipanggil.
  • Dengan secara eksplisit menentukan <number> atau <string>, anda sedang menentukan jenis tersebut.

Jenis generik berfungsi tanpa spesifikasi eksplisit kerana TypeScript menjalankan inferens jenis.

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

Kekangan pada Generik

Dengan meletakkan kekangan pada generik, anda boleh mengehadkan mereka untuk hanya menerima jenis tertentu.

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 bahawa T mesti merupakan jenis dengan sifat length. Oleh itu, jenis tanpa sifat length tidak akan diterima.

Kelas Generik

Kelas juga boleh didefinisikan menggunakan generik. Kelas generik menawarkan jenis yang fleksibel untuk sifat dan kaedah.

 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> mengisytiharkan jenis T yang digunakan dalam kelas sebagai generik. Ini membolehkan kelas yang sama digunakan semula untuk jenis yang berbeza.

Antara Muka Generik

Generik juga boleh digunakan bersama antara muka.

 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 jenis generik menggunakan Pair<T, U>, anda boleh mendefinisikan objek dengan gabungan pelbagai jenis.

Argumen Jenis Lalai

Ia juga boleh menentukan jenis lalai untuk argumen jenis 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 jenis lalai kepada string dengan <T = string>. Jika tiada jenis dinyatakan secara jelas, T akan menjadi jenis string.

Alias Jenis Generik

Generik juga boleh digunakan sebagai alias jenis (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 mengandungi data jenis T. Dengan cara ini, anda boleh mencipta alias jenis fleksibel menggunakan generik.

Pelbagai Jenis Generik

Dengan menggunakan pelbagai jenis generik, anda boleh mentakrifkan fungsi dan kelas yang lebih serba boleh.

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 mengambil dua jenis berbeza T dan U dan menggabungkannya untuk mengembalikan objek baharu.

Ringkasan

  • Generik membolehkan kod boleh guna semula dan selamat jenis dengan menganggap jenis sebagai parameter.
  • Dengan menggunakan generik dalam fungsi, kelas, dan antara muka, anda boleh menulis logik fleksibel yang mengendalikan pelbagai jenis.
  • Dengan menambah kekangan pada argumen jenis atau menetapkan argumen jenis lalai, anda boleh mengawal skop generik.

Dengan menggunakan generik, anda boleh menulis kod bebas jenis dan serba guna, memanfaatkan sepenuhnya sistem jenis TypeScript yang kuat.

Anda boleh mengikuti artikel di atas menggunakan Visual Studio Code di saluran YouTube kami. Sila lihat juga saluran YouTube kami.

YouTube Video