Giới thiệu Generics

Generics cho phép viết hàm, lớp, giao diện mà không cố định kiểu dữ liệu. Khi cần tái sử dụng logic cho nhiều kiểu, Generics là giải pháp.

Tại sao dùng Generics

Tránh any, giảm lỗi runtime, tăng khả năng tự động hoàn thiện trong IDE. Kiểm tra kiểu tại thời điểm biên dịch, bảo đảm tính nhất quán.

Cú pháp cơ bản

Định nghĩa hàm generic bằng ký hiệu <T> sau tên hàm.

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

Gọi hàm, TypeScript suy ra kiểu từ đối số.

let num = identity(5); // T inferred as number
let str = identity('hello'); // T inferred as string

Ràng buộc (Constraints)

Đặt extends để giới hạn kiểu có thuộc tính hoặc phương thức nhất định.

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

Áp dụng cho mảng, chuỗi, hoặc bất kỳ đối tượng nào có length.

Kiểu mặc định (Default Types)

Định nghĩa giá trị mặc định khi không truyền kiểu.

function createArray<T = number>(length: number, value: T): T[] {
    return Array.from({ length }, () => value);
}

Gọi createArray(3, 'a') trả về string[], còn createArray(2, 0) trả về number[].

Generics trong React Props

Component nhận danh sách và hàm render cho từng mục.

interface ListProps<T> {
    items: T[];
    renderItem: (item: T) => React.ReactNode;
}

const List = <T,>(props: ListProps<T>) => (
    <ul>
        {props.items.map((item, i) => (
            <li key={i}>{props.renderItem(item)}</li>
        ))}
    </ul>
);

Sử dụng: <List items={[1,2,3]} renderItem={n => n * 2} /> hoặc <List items={[{name:'A'},{name:'B'}]} renderItem={p => p.name} />.

Lợi ích thực tế

  • Code ngắn gọn, không lặp lại kiểu.
  • Kiểm tra chặt chẽ, giảm bug.
  • Tăng năng suất khi làm việc với thư viện lớn.

Áp dụng Generics trong dịch vụ API, hàm xử lý dữ liệu, hoặc component UI để đạt hiệu quả tối đa.

Để nắm vững Generics và các kỹ thuật nâng cao, học tập bài bản giúp nhanh chóng áp dụng. Tham khảo khóa học "Lập trình TypeScript từ cơ bản đến nâng cao" tại đây.