Optional chaining là một tính năng hữu ích trong TypeScript (cũng như trong JavaScript) cho phép bạn truy cập các thuộc tính sâu bên trong của một đối tượng mà không cần kiểm tra từng cấp độ tồn tại của đối tượng. Điều này giúp giảm thiểu lỗi khi cố gắng truy cập các thuộc tính của một đối tượng có thể không tồn tại. Bài viết này sẽ hướng dẫn bạn cách sử dụng optional chaining và lý do tại sao nó lại quan trọng.

Cú pháp Optional Chaining

Optional chaining sử dụng dấu hỏi chấm ?. để kiểm tra xem một thuộc tính có tồn tại hay không trước khi cố gắng truy cập nó. Nếu thuộc tính tồn tại, giá trị của nó sẽ được trả về; nếu không, biểu thức sẽ trả về undefined thay vì gây ra lỗi.

Ví dụ cơ bản về Optional Chaining

Giả sử bạn có một đối tượng với cấu trúc lồng nhau như sau:

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

const user: User = {
    name: "Alice",
    address: {
        street: "123 Main St",
        // city không được định nghĩa
    },
};

// Truy cập thuộc tính 'city' mà không có optional chaining
const city1 = user.address && user.address.city; // 'undefined'
console.log(city1); // undefined

// Truy cập thuộc tính 'city' với optional chaining
const city2 = user.address?.city; // 'undefined'
console.log(city2); // undefined

Trong ví dụ này, nếu bạn không sử dụng optional chaining, bạn sẽ phải kiểm tra xem address có tồn tại hay không trước khi truy cập city. Điều này có thể làm cho mã trở nên phức tạp hơn.

Optional Chaining với Mảng

Optional chaining cũng có thể được sử dụng với các phần tử của mảng. Dưới đây là một ví dụ:

interface Product {
    name: string;
    reviews?: {
        rating?: number;
    }[];
}

const product: Product = {
    name: "Gadget",
    reviews: [
        { rating: 5 },
        // review thứ hai không có rating
    ],
};

// Truy cập rating của review thứ hai
const secondReviewRating = product.reviews?.[1]?.rating; // 'undefined'
console.log(secondReviewRating); // undefined

Giải thích ví dụ

  1. Khi sử dụng ?.: Nếu reviews không tồn tại hoặc nếu reviews[1] không tồn tại, thì secondReviewRating sẽ là undefined thay vì gây ra lỗi.
  2. Sử dụng với phương thức: Bạn có thể sử dụng optional chaining với các phương thức:
const length = product.reviews?.length; // 2
console.log(length); // 2

Optional Chaining với nullundefined

Optional chaining cũng sẽ trả về undefined nếu bạn truy cập một thuộc tính của một đối tượng có giá trị là null hoặc undefined. Điều này giúp tránh lỗi TypeError.

const user2: User | null = null;

// Truy cập thuộc tính 'address' của user2
const userAddress = user2?.address; // 'undefined'
console.log(userAddress); // undefined

Lý do sử dụng Optional Chaining

1. Giảm thiểu lỗi

Sử dụng optional chaining giúp giảm thiểu nguy cơ gặp lỗi TypeError do truy cập các thuộc tính trên null hoặc undefined. Điều này làm cho mã trở nên an toàn hơn.

2. Cải thiện khả năng đọc mã

Optional chaining giúp mã nguồn trở nên ngắn gọn và dễ hiểu hơn. Thay vì viết nhiều câu lệnh điều kiện để kiểm tra sự tồn tại của thuộc tính, bạn chỉ cần sử dụng ?. để thực hiện điều đó một cách trực quan.

3. Tối ưu hóa hiệu suất

Khi bạn sử dụng optional chaining, JavaScript sẽ dừng lại ngay lập tức khi gặp một giá trị null hoặc undefined, giúp giảm thiểu việc thực hiện các phép truy cập không cần thiết.

Kết luận

Optional chaining là một tính năng mạnh mẽ và tiện lợi trong TypeScript, cho phép bạn truy cập các thuộc tính của đối tượng một cách an toàn mà không cần phải kiểm tra từng cấp độ. Bằng cách sử dụng cú pháp ?., bạn có thể viết mã ngắn gọn và dễ hiểu hơn, đồng thời giảm thiểu các lỗi tiềm ẩn liên quan đến việc truy cập thuộc tính của các đối tượng không xác định. Việc nắm vững cách sử dụng optional chaining sẽ giúp bạn viết mã chất lượng cao hơn trong các ứng dụng TypeScript của mình.