Union và Intersection trong TypeScript

Tạo bởi Hoàng Vũ, chỉnh sửa cuối lúc 29 tháng 1, 2025

TypeScript cung cấp hai tính năng mạnh mẽ để làm việc với kiểu dữ liệu:

  • Union (|): Cho phép một biến có thể thuộc nhiều kiểu khác nhau.
  • Intersection (&): Kết hợp nhiều kiểu thành một kiểu mới, chứa tất cả thuộc tính của các kiểu thành phần.

Cùng tìm hiểu chi tiết về hai tính năng này!

1. Union Type (|) – Kết hợp nhiều kiểu dữ liệu

Union (|) cho phép một biến có thể thuộc một trong nhiều kiểu khác nhau.

1.1. Union với kiểu dữ liệu cơ bản

let value: number | string;

value = 10; // ✅ Hợp lệ
value = "Hello"; // ✅ Hợp lệ
// value = true; // ❌ Lỗi: Type 'boolean' is not assignable to type 'number | string'.

1.2. Union trong tham số hàm

function printId(id: number | string) {
  console.log("ID:", id);
}

printId(123); // Output: ID: 123
printId("abc"); // Output: ID: abc

Tuy nhiên, khi sử dụng Union, TypeScript không tự động suy luận kiểu cụ thể, nên ta cần kiểm tra kiểu trước khi thao tác:

function doubleValue(value: number | string) {
  if (typeof value === "number") {
    return value * 2; // ✅ Hợp lệ vì đã kiểm tra kiểu
  } else {
    return value.repeat(2); // ✅ Hợp lệ với kiểu string
  }
}

console.log(doubleValue(5)); // Output: 10
console.log(doubleValue("Hi")); // Output: HiHi

1.3. Union trong kiểu đối tượng

Union cũng có thể dùng với kiểu đối tượng để tạo kiểu linh hoạt hơn.

type Dog = { bark: () => void };
type Cat = { meow: () => void };

type Pet = Dog | Cat;

function makeSound(animal: Pet) {
  if ("bark" in animal) {
    animal.bark(); // ✅ Chỉ gọi bark nếu là Dog
  } else {
    animal.meow(); // ✅ Chỉ gọi meow nếu là Cat
  }
}

2. Intersection Type (&) – Kết hợp nhiều kiểu dữ liệu

Intersection (&) kết hợp nhiều kiểu thành một kiểu mới, chứa tất cả các thuộc tính của các kiểu thành phần.

2.1. Intersection với kiểu đối tượng

type Person = {
  name: string;
  age: number;
};

type Employee = {
  company: string;
  position: string;
};

type Developer = Person & Employee;

let dev: Developer = {
  name: "Alice",
  age: 30,
  company: "Tech Corp",
  position: "Software Engineer",
};

Lúc này, biến dev phải có đủ thuộc tính của cả PersonEmployee.

2.2. Intersection trong tham số hàm

function introduce(person: Person & Employee) {
  console.log(
    `Tên: ${person.name}, Tuổi: ${person.age}, Công ty: ${person.company}, Vị trí: ${person.position}`
  );
}

introduce(dev); // Output: Tên: Alice, Tuổi: 30, Công ty: Tech Corp, Vị trí: Software Engineer

2.3. Intersection với kiểu tùy chỉnh

Có thể kết hợp typeinterface:

interface A {
  a: string;
}

interface B {
  b: number;
}

type C = A & B;

let obj: C = {
  a: "Hello",
  b: 42,
};

Lúc này, obj phải có cả thuộc tính ab.

3. So sánh Union (|) và Intersection (&)

| Đặc điểm | Union (|) | Intersection (&) | |----------|------------|--------------------| | Mục đích | Chọn một trong nhiều kiểu | Kết hợp tất cả các kiểu | | Sử dụng với kiểu cơ bản | ✅ Hỗ trợ (number | string) | ❌ Không áp dụng | | Sử dụng với kiểu đối tượng | ✅ Hỗ trợ (type A | type B) | ✅ Hỗ trợ (type A & type B) | | Ràng buộc | Ít ràng buộc hơn, cho phép giá trị thuộc một trong các kiểu | Chặt chẽ hơn, yêu cầu có tất cả thuộc tính của các kiểu |

Ví dụ trực quan

// Union: Chỉ cần có một trong hai
type Fish = { swim: () => void };
type Bird = { fly: () => void };

let pet1: Fish | Bird = { swim: () => console.log("Swimming") }; // ✅ Hợp lệ
let pet2: Fish | Bird = { fly: () => console.log("Flying") }; // ✅ Hợp lệ

// Intersection: Cần có cả hai
let pet3: Fish & Bird = {
  swim: () => console.log("Swimming"),
  fly: () => console.log("Flying"),
}; // ✅ Hợp lệ vì có đủ cả swim và fly

4. Khi nào nên dùng UnionIntersection?

Trường hợp Nên dùng
Khi cần một kiểu có thể nhận một trong nhiều giá trị **Union (`
Khi cần một kiểu chứa tất cả thuộc tính của nhiều kiểu khác nhau Intersection (&)
Khi làm việc với kiểu dữ liệu cơ bản (`number string`)
Khi kết hợp nhiều kiểu đối tượng (e.g., Person & Employee) Intersection (&)

Ví dụ thực tế:

  • Union (|) hữu ích khi một biến có thể chứa nhiều loại giá trị như number | string.
  • Intersection (&) hữu ích khi kết hợp nhiều kiểu đối tượng như Person & Employee để tạo một kiểu phức tạp hơn.

5. Tổng kết

  • Union (|): Cho phép biến hoặc đối tượng có thể thuộc nhiều kiểu khác nhau.
  • Intersection (&): Kết hợp nhiều kiểu thành một kiểu mới, chứa tất cả thuộc tính của các kiểu thành phần.
  • Union linh hoạt hơn, còn Intersection chặt chẽ hơn, yêu cầu đối tượng có đủ thuộc tính từ tất cả các kiểu.
Website Logo

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.

Bình luận

Website Logo

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.

Liên hệ công việc qua email dưới đây.

lhvuctu@gmail.com

Chúng Tôi Trên

Bạn đang muốn học về lập trình website?

Bạn cần nâng cao kiến thức chuyên nghiệp hơn để nâng cao cơ hội nghề nghiệp? Liên hệ