Utility Types trong TypeScript là một tập hợp các loại kiểu dữ liệu được tích hợp sẵn, cho phép bạn thao tác với các kiểu dữ liệu một cách dễ dàng và hiệu quả hơn. Chúng rất hữu ích trong việc xử lý các kiểu dữ liệu phức tạp, giúp bạn tiết kiệm thời gian và cải thiện tính rõ ràng trong mã nguồn.

Bài viết này là một phần của chuỗi học TypeScript trên "codetuthub.com", cùng với các bài học khác như TypeScript Simple Types, TypeScript Functions, và TypeScript Classes.

1. Tại sao cần Utility Types?

Utility types giúp bạn thực hiện các thao tác thường gặp trên các kiểu dữ liệu mà không cần phải định nghĩa lại từ đầu. Điều này làm giảm độ phức tạp trong mã và cải thiện khả năng bảo trì.

2. Một số Utility Types phổ biến

2.1 Partial

Partial là một utility type cho phép bạn biến một kiểu thành một kiểu có tất cả các thuộc tính là tùy chọn. Điều này rất hữu ích khi bạn muốn cập nhật một phần của một đối tượng mà không cần chỉ định tất cả các thuộc tính.

Ví dụ

ts
interface User {
    id: number;
    name: string;
    email: string;
}

function updateUser(id: number, userUpdates: Partial<User>): void {
    // Logic để cập nhật người dùng
}

updateUser(1, { name: "Alice" }); // Chỉ cập nhật tên

2.2 Required

Required là utility type ngược lại với Partial. Nó biến tất cả các thuộc tính của một kiểu thành bắt buộc.

Ví dụ

ts
interface User {
    id?: number; // Thuộc tính tùy chọn
    name?: string;
}

const newUser: Required<User> = {
    id: 1, // Bắt buộc
    name: "Bob" // Bắt buộc
};

2.3 Readonly

Readonly cho phép bạn biến tất cả các thuộc tính của một kiểu thành chỉ đọc, có nghĩa là chúng không thể được thay đổi sau khi được gán giá trị ban đầu.

Ví dụ

ts
interface Point {
    x: number;
    y: number;
}

const p: Readonly<Point> = { x: 10, y: 20 };

// p.x = 15; // Lỗi: Cannot assign to 'x' because it is a read-only property.

2.4 Record

Record là utility type cho phép bạn tạo một đối tượng với các thuộc tính được chỉ định là một kiểu cụ thể.

Ví dụ

ts
type PageInfo = {
    title: string;
    content: string;
};

const pages: Record<string, PageInfo> = {
    home: {
        title: "Home Page",
        content: "Welcome to the homepage."
    },
    about: {
        title: "About Page",
        content: "Information about us."
    }
};

2.5 Pick

Pick cho phép bạn tạo một kiểu mới bằng cách chọn một số thuộc tính từ một kiểu có sẵn.

Ví dụ

ts
interface User {
    id: number;
    name: string;
    email: string;
}

type UserPreview = Pick<User, "id" | "name">;

const user: UserPreview = {
    id: 1,
    name: "Charlie"
};

2.6 Omit

Omit ngược lại với Pick, cho phép bạn tạo một kiểu mới bằng cách loại bỏ một số thuộc tính từ một kiểu có sẵn.

Ví dụ

ts
type UserWithoutEmail = Omit<User, "email">;

const user: UserWithoutEmail = {
    id: 1,
    name: "Diana"
    // email không có ở đây
};

3. Kết luận

Utility types trong TypeScript là một công cụ mạnh mẽ giúp bạn làm việc với các kiểu dữ liệu một cách hiệu quả hơn. Bằng cách sử dụng các utility types như Partial, Required, Readonly, Record, Pick, và Omit, bạn có thể tối ưu hóa mã của mình và cải thiện tính rõ ràng cũng như khả năng bảo trì. Để tìm hiểu thêm về TypeScript, hãy tham khảo các bài học liên quan trên "codetuthub.com" như TypeScript Simple Types, TypeScript Functions, và TypeScript Classes.