hoc-lap-trinh-18

Generics trong TypeScript cho phép bạn tạo ra các thành phần có thể làm việc với nhiều loại dữ liệu mà vẫn duy trì tính an toàn về kiểu dữ liệu. Đây là một tính năng mạnh mẽ giúp bạn viết mã linh hoạt và tái sử dụng được.

Cách sử dụng Generics trong TypeScript

1. Generics với Hàm

Bạn có thể sử dụng generics để định nghĩa các hàm có thể làm việc với nhiều kiểu dữ liệu khác nhau.

function identity<T>(arg: T): T {
    return arg;
}

let output1 = identity<string>("Hello, Generics!"); // Output: "Hello, Generics!"
let output2 = identity<number>(123); // Output: 123

Trong ví dụ này, <T> là một generic type parameter. Nó cho phép hàm identity nhận vào một đối số arg và trả về giá trị có cùng kiểu với arg.

2. Generics với Class

Bạn có thể sử dụng generics để định nghĩa các lớp có thể làm việc với nhiều kiểu dữ liệu khác nhau.

class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) {
    return x + y;
};

console.log(myGenericNumber.add(myGenericNumber.zeroValue, 5)); // Output: 5

3. Generics với Interface

Bạn có thể sử dụng generics để định nghĩa các interface có thể làm việc với nhiều kiểu dữ liệu khác nhau.

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

let pair: Pair<string, number> = {
    first: "hello",
    second: 42
};

console.log(pair); // Output: { first: 'hello', second: 42 }

4. Generics với Constraints

Đôi khi, bạn muốn giới hạn loại giá trị mà một generic có thể nhận. Bạn có thể làm điều này bằng cách sử dụng constraints

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);
    return arg;
}

loggingIdentity("Hello, Generics!"); // Output: 16
loggingIdentity([1, 2, 3, 4]); // Output: 4

Trong ví dụ này, T được ràng buộc với interface Lengthwise, có nghĩa là T phải có thuộc tính length.

Ví dụ minh họa

  1. Generics với Mảng:
function getArray<T>(items: T[]): T[] {
    return new Array<T>().concat(items);
}

let numArray = getArray<number>([1, 2, 3]);
let strArray = getArray<string>(["hello", "world"]);

numArray.push(4); // OK
strArray.push("!");

console.log(numArray); // Output: [1, 2, 3, 4]
console.log(strArray); // Output: ["hello", "world", "!"]

2. Generics với Hàm và Interface:

interface KeyValuePair<K, V> {
    key: K;
    value: V;
}

function displayKeyValue<K, V>(kvp: KeyValuePair<K, V>): void {
    console.log(`key = ${kvp.key}, value = ${kvp.value}`);
}

let kvp1: KeyValuePair<number, string> = { key: 1, value: "Steve" };
let kvp2: KeyValuePair<string, string> = { key: "username", value: "JohnDoe" };

displayKeyValue(kvp1); // Output: key = 1, value = Steve
displayKeyValue(kvp2); // Output: key = username, value = JohnDoe

Generics giúp mã của bạn linh hoạt và mạnh mẽ hơn bằng cách cho phép bạn định nghĩa các thành phần mà có thể làm việc với bất kỳ kiểu dữ liệu nào, trong khi vẫn giữ được tính an toàn về kiểu dữ liệu.

By hoadv

Leave a Reply

Your email address will not be published. Required fields are marked *