Trong TypeScript, việc xử lý các giá trị có thể là null hoặc undefined là một phần quan trọng để đảm bảo mã hoạt động ổn định. Hai tính năng nổi bật giúp quản lý vấn đề này là Optional Chaining (?.) và Non-null Assertion Operator (!). Trong khi Optional Chaining cho phép bạn truy cập an toàn các thuộc tính lồng nhau mà không lo lắng về việc thuộc tính đó có tồn tại hay không, Non-null Assertion Operator cho phép bạn chỉ định rằng một giá trị sẽ không phải là null hoặc undefined, giúp loại bỏ các cảnh báo từ TypeScript. Bài viết này sẽ phân tích điểm khác biệt cơ bản giữa hai tính năng này và hướng dẫn cách sử dụng chúng một cách hiệu quả trong mã nguồn của bạn.

1. Định Nghĩa

1.1. Optional Chaining (?.)

Optional Chaining cho phép bạn truy cập các thuộc tính lồng nhau của một đối tượng mà không cần lo lắng về việc thuộc tính đó có thể là null hoặc undefined. Nếu một trong các thuộc tính là null hoặc undefined, nó sẽ trả về undefined thay vì gây ra lỗi.

Ví dụ:

interface User {
  name: string;
  address?: {
    street: string;
    city: string;
  };
}

const user: User = { name: "Alice" };

console.log(user.address?.street); // undefined

Trong ví dụ này, user.address không tồn tại, do đó user.address?.street trả về undefined.

1.2. Non-null Assertion Operator (!)

Non-null Assertion Operator cho phép bạn chỉ định rằng một giá trị không thể là null hoặc undefined tại một thời điểm cụ thể trong mã. Điều này hữu ích khi bạn biết chắc rằng một giá trị sẽ tồn tại, và bạn muốn TypeScript không cảnh báo rằng giá trị đó có thể là null hoặc undefined.

Ví dụ:

interface User {
  name: string;
  address?: {
    street: string;
    city: string;
  };
}

const user: User = { name: "Alice" };

console.log(user.address!.street); // Lỗi sẽ xảy ra nếu `address` là `undefined`

Trong ví dụ này, việc sử dụng user.address! thông báo cho TypeScript rằng address không thể là null hoặc undefined. Nếu nó thực sự là undefined, mã sẽ gây ra lỗi tại thời điểm thực thi.

2. Cách Hoạt Động

2.1. Optional Chaining

  • Khi sử dụng Optional Chaining, nếu thuộc tính không tồn tại, mã sẽ không gây ra lỗi mà sẽ trả về undefined.
  • Optional Chaining không yêu cầu bạn phải đảm bảo rằng giá trị tồn tại; nó an toàn cho việc truy cập.

2.2. Non-null Assertion Operator

  • Khi sử dụng Non-null Assertion Operator, bạn cần chắc chắn rằng giá trị thực sự tồn tại tại thời điểm truy cập.
  • Nếu giá trị là null hoặc undefined, mã sẽ gây ra lỗi trong quá trình thực thi.

3. Mục Đích Sử Dụng

3.1. Optional Chaining

  • Dùng khi bạn không chắc chắn về sự tồn tại của thuộc tính và muốn truy cập một cách an toàn.
  • Thích hợp cho việc truy cập các thuộc tính lồng nhau mà có thể không tồn tại.

3.2. Non-null Assertion Operator

  • Dùng khi bạn biết chắc chắn rằng giá trị sẽ tồn tại và muốn loại bỏ cảnh báo từ TypeScript.
  • Thích hợp trong trường hợp bạn đã kiểm tra giá trị ở một nơi khác trong mã, nhưng không muốn TypeScript ngăn cản bạn sử dụng giá trị đó.

4. Kết Luận

Tóm lại, Optional Chaining và Non-null Assertion Operator phục vụ các mục đích khác nhau trong TypeScript. Optional Chaining là công cụ an toàn để truy cập các thuộc tính có thể không tồn tại, trong khi Non-null Assertion Operator cho phép bạn xác nhận rằng một giá trị chắc chắn sẽ tồn tại. Việc sử dụng đúng cách sẽ giúp bạn viết mã rõ ràng và an toàn hơn.