Trong TypeScript, Type AliasesInterfaces đều được sử dụng để định nghĩa cấu trúc của đối tượng, giúp mã nguồn trở nên rõ ràng và dễ bảo trì. Mặc dù có nhiều điểm tương đồng, nhưng chúng cũng có sự khác biệt và được sử dụng trong các tình huống khác nhau. Bài viết này sẽ giúp bạn hiểu rõ hơn về cách sử dụng type aliases và interfaces trong TypeScript.

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 Tuples, và TypeScript Enums.

1. Định nghĩa type aliases

Type Aliases cho phép bạn định nghĩa một kiểu mới bằng cách sử dụng từ khóa type. Type alias có thể được sử dụng để mô tả một kiểu đơn giản hoặc một cấu trúc phức tạp như đối tượng hoặc hàm.

Ví dụ về type aliases

ts
type Point = {
    x: number;
    y: number;
};

let pointA: Point = {
    x: 10,
    y: 20
};

Trong ví dụ này, Point là một type alias mô tả một đối tượng có hai thuộc tính xy.

2. Khai báo interfaces

Interfaces được sử dụng để định nghĩa cấu trúc của một đối tượng. Chúng có thể được mở rộng và kết hợp với nhau, cho phép bạn tạo ra các kiểu phức tạp hơn. Interfaces thường được sử dụng trong lập trình hướng đối tượng.

Ví dụ về interfaces

ts
interface Person {
    name: string;
    age: number;
}

let personA: Person = {
    name: "Alice",
    age: 25
};

Trong ví dụ này, Person là một interface mô tả cấu trúc của một đối tượng với hai thuộc tính nameage.

3. So sánh type aliases và interfaces

Mặc dù cả hai đều có thể được sử dụng để định nghĩa cấu trúc của đối tượng, nhưng chúng có một số khác biệt:

3.1 Mở rộng

  • Interfaces có thể được mở rộng bằng cách sử dụng từ khóa extends, cho phép bạn tạo ra các interface mới dựa trên các interface đã có.
ts
interface Employee extends Person {
    employeeId: number;
}

let employeeA: Employee = {
    name: "Bob",
    age: 30,
    employeeId: 101
};
  • Type Aliases không thể được mở rộng. Tuy nhiên, bạn có thể kết hợp các type aliases bằng cách sử dụng giao thoa.
ts
type User = {
    name: string;
    age: number;
};

type Admin = User & {
    role: string;
};

let adminA: Admin = {
    name: "Charlie",
    age: 35,
    role: "Administrator"
};

3.2 Tính kế thừa

  • Interfaces có thể được kế thừa từ nhiều interfaces khác nhau, điều này rất hữu ích trong các dự án lớn.
ts
interface Contact {
    email: string;
}

interface ExtendedPerson extends Person, Contact {
    phone: string;
}

4. Tính năng tùy chọn và đọc-ghi

Cả type aliases và interfaces đều hỗ trợ tính năng tùy chọn và chỉ định thuộc tính đọc-ghi.

Ví dụ

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

interface Car {
    readonly brand: string; // Thuộc tính chỉ đọc
    model: string;
}

const carA: Car = {
    brand: "Toyota",
    model: "Camry"
};

// carA.brand = "Honda"; // Lỗi: Cannot assign to 'brand' because it is a read-only property.

5. Khi nào nên sử dụng type aliases hay interfaces

  • Sử dụng type aliases: Khi bạn cần định nghĩa các kiểu phức tạp như các hàm, unions, hoặc khi bạn không cần tính kế thừa.
  • Sử dụng interfaces: Khi bạn muốn mở rộng, kế thừa, hoặc khi bạn cần tạo ra các cấu trúc phức tạp cho các đối tượng.

6. Kết luận

TypeScript cung cấp cả type aliases và interfaces để giúp bạn định nghĩa và tổ chức cấu trúc của dữ liệu trong ứng dụng của mình. Cả hai đều rất mạnh mẽ và có thể được sử dụng trong nhiều tình huống khác nhau. Hiểu rõ sự khác biệt và cách sử dụng chúng sẽ giúp bạn viết mã rõ ràng và dễ bảo trì hơn. Để 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 Tuples, và TypeScript Enums.