0
0
Lập trình
Admin Team
Admin Teamtechmely

Sự Khác Biệt Giữa Void và Undefined Trong TypeScript

Đăng vào 4 tháng trước

• 3 phút đọc

🔥 Giới Thiệu

Khi một hàm trong TypeScript không trả về giá trị nào, liệu nó có trả về void hay undefined? Tại thời điểm chạy, JavaScript luôn trả về undefined. Tuy nhiên, tại thời điểm biên dịch, TypeScript hiển thị là void. Hãy cùng tìm hiểu sự mâu thuẫn này.


🕹 Quan Điểm Từ Thời Điểm Chạy (JavaScript)

JavaScript không có khái niệm void. Mỗi lần gọi hàm đều trả về một giá trị nào đó. Nếu bạn không trả về giá trị một cách rõ ràng, nó sẽ trả về undefined.

typescript Copy
function greet(name: string) {
  console.log(`Xin chào, ${name}!`);
}

console.log(greet("Arka")); 
// Kết quả:
// Xin chào, Arka!
// undefined

👉 Tại thời điểm chạy, giá trị trả về thực tế luôn là undefined.


🛠 Quan Điểm Từ Thời Điểm Biên Dịch (TypeScript)

TypeScript không thực thi mã của bạn. Nó chỉ mô tả ý định của bạn tại thời điểm biên dịch. Khi bạn không trả về bất kỳ giá trị nào, TypeScript đánh dấu kiểu trả về là void.

typescript Copy
function greet(name: string): void {
  console.log(`Xin chào, ${name}!`);
}

const result = greet("Arka"); 
// result có kiểu void (không phải undefined)

👉 Tại thời điểm biên dịch, void có nghĩa là:
“Đừng dựa vào hoặc sử dụng giá trị trả về.”


❌ Tại Sao Không Chỉ Dùng undefined?

Hãy thử làm cho kiểu trả về là undefined:

typescript Copy
function greet(name: string): undefined {
  console.log(`Xin chào, ${name}!`);
}

⚡ Lỗi biên dịch:

Copy
Hàm thiếu câu lệnh trả về kết thúc và kiểu trả về không bao gồm 'undefined'

Bởi vì nếu bạn sử dụng undefined như một kiểu dữ liệu, TypeScript kỳ vọng bạn phải trả về undefined một cách rõ ràng:

typescript Copy
function doNothing(): undefined {
  return undefined; // ✅ hợp lệ
}

Vì vậy:

  • Giá trị tại thời điểm chạy: undefined
  • Kiểu tại thời điểm biên dịch: void (trừ khi bạn cố tình ép thành undefined)

🚩 Hàm Async

Cùng quy tắc này áp dụng cho các hàm bất đồng bộ:

typescript Copy
async function greetAsync(name: string): Promise<void> {
  console.log(`Xin chào, ${name}!`);
}
  • Tại thời điểm chạy: trả về Promise.resolve(undefined)
  • Tại thời điểm biên dịch: kiểu trả về là Promise<void>

Phiên bản Arrow:

typescript Copy
const greetAsync = async (name: string): Promise<void> => {
  console.log(`Xin chào, ${name}!`);
};

🏗 Ví Dụ Thực Tế

typescript Copy
function logger(message: string): void {
  console.log(`[LOG]: ${message}`);
}

async function saveData(data: string): Promise<void> {
  await new Promise(res => setTimeout(res, 1000));
  logger(`Đã lưu: ${data}`);
}
  • Tại thời điểm chạy: logger trả về undefined, saveData giải quyết thành undefined.
  • Tại thời điểm biên dịch: TypeScript hiển thị voidPromise<void>.

💡 Những Điểm Chính

  • Tại thời điểm chạy (JavaScript): Các hàm không trả về giá trị → luôn trả về undefined.
  • Tại thời điểm biên dịch (TypeScript): Sử dụng void (hoặc Promise<void>) để báo hiệu “đừng sử dụng giá trị trả về.”
  • undefined như một kiểu: Quá nghiêm ngặt; yêu cầu trả về undefined một cách rõ ràng.
  • Nguyên tắc: Sử dụng void cho các hàm không có giá trị trả về có ý nghĩa.
  • Vậy nên, lần tới khi bạn thấy void trong TypeScript, hãy nhớ: đó là một sự trừu tượng tại thời điểm biên dịch, trong khi undefined là giá trị thực tế tại thời điểm chạy.

🛠 Thực Hành Tốt Nhất

  • Sử dụng void cho các hàm mà giá trị trả về không quan trọng.
  • Ghi rõ ràng ý định của bạn bằng cách sử dụng các kiểu dữ liệu thích hợp.

⚠️ Cạm Bẫy Phổ Biến

  • Nhầm lẫn giữa voidundefined có thể dẫn đến lỗi không mong muốn trong mã của bạn.
  • Không nên sử dụng undefined như một kiểu trả về trừ khi bạn chắc chắn rằng bạn sẽ trả về giá trị đó.

⚡ Mẹo Hiệu Suất

  • Kiểm tra mã của bạn để đảm bảo rằng không có hàm nào vô tình trả về giá trị không cần thiết.
  • Tối ưu hóa các hàm bất đồng bộ để đảm bảo chúng không chậm chễ trong quá trình thực thi.

❓ Câu Hỏi Thường Gặp

1. voidundefined có khác nhau không?
Có, void là kiểu chỉ định không có giá trị trả về, trong khi undefined là giá trị mà JavaScript trả về khi không có gì được trả lại.

2. Tôi có thể sử dụng undefined cho các hàm không trả về giá trị không?
Không, bạn nên sử dụng void cho các hàm như vậy.

3. Tại sao TypeScript lại không cho phép undefined làm kiểu trả về cho các hàm không trả giá trị?
Bởi vì undefined yêu cầu bạn phải trả về giá trị đó một cách rõ ràng, điều này có thể gây ra lỗi trong mã.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào