0
0
Lập trình
Sơn Tùng Lê
Sơn Tùng Lê103931498422911686980

Sự Khác Biệt Giữa TypeScript `unknown` và `any`

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

• 4 phút đọc

Sự Khác Biệt Giữa TypeScript unknownany

Trong TypeScript, cả unknownany đều đại diện cho các giá trị có kiểu không rõ ràng tại thời điểm biên dịch. Ban đầu, chúng có thể trông giống nhau, nhưng hành vi và tác động của chúng đến an toàn kiểu rất khác nhau.

Việc chọn đúng kiểu có thể tạo ra sự khác biệt giữa mã an toàn, dễ bảo trì và một mã nguồn đầy rẫy sự cố thời gian chạy.

Bài viết này sẽ phân tích sự khác biệt, kèm theo các ví dụ, thực hành tốt nhất và bảng tóm tắt để tham khảo nhanh.


Các Sự Khác Biệt Chính Giữa unknownany

1. An Toàn Kiểu

  • any: Hoàn toàn vô hiệu hóa việc kiểm tra kiểu. Bạn có thể thực hiện bất kỳ thao tác nào trên nó, ngay cả những thao tác không hợp lệ, và trình biên dịch sẽ không báo lỗi.
  • unknown: Là sự thay thế an toàn về kiểu. Bạn phải thu hẹp hoặc khẳng định kiểu trước khi sử dụng nó.
typescript Copy
let valueAny: any;
let valueUnknown: unknown;

valueAny = "Xin chào";
console.log(valueAny.toUpperCase()); // ✅ Biên dịch thành công, có thể lỗi thời gian chạy

valueUnknown = "Xin chào";
console.log(valueUnknown.toUpperCase()); // ❌ Lỗi: phải thu hẹp trước

2. Hạn Chế Sử Dụng

  • any: Có thể gán cho bất kỳ kiểu nào và cho phép bất kỳ thao tác nào.
  • unknown: Cần kiểm tra loại hoặc khẳng định rõ ràng.
typescript Copy
let valueAny: any = "Xin chào";
let str: string = valueAny; // ✅ Hoạt động, nhưng không an toàn
valueAny.nonExistentMethod(); // ✅ Biên dịch, 💥 lỗi thời gian chạy

let valueUnknown: unknown = "Xin chào";
// ❌ let str2: string = valueUnknown;
if (typeof valueUnknown === "string") {
  console.log(valueUnknown.toUpperCase()); // ✅ An toàn
}

3. Quy Tắc Gán

  • any: Hai chiều - có thể gán từ và đến bất cứ thứ gì.
  • unknown: Bất cứ thứ gì có thể được gán cho unknown, nhưng unknown chỉ có thể được gán cho any hoặc unknown (trừ khi đã thu hẹp).
typescript Copy
let valueAny: any;
let valueUnknown: unknown;

valueAny = 42;
let num1: number = valueAny; // ✅ Hoạt động

valueUnknown = 42;
// ❌ let num2: number = valueUnknown;

let anyVar: any = valueUnknown;   // ✅ Cho phép
let unknownVar: unknown = valueAny; // ✅ Cho phép

4. Triết Lý Sử Dụng

  • any:

    • Bỏ qua hệ thống kiểu.
    • Thường dùng trong di chuyển từ JavaScript sang TypeScript.
    • Hữu ích cho việc tạo mẫu nhanh hoặc làm việc với thư viện không có định nghĩa kiểu.
  • unknown:

    • Buộc phải kiểm tra rõ ràng.
    • Thích hợp để xử lý phản hồi API, đầu vào của người dùng, hoặc dữ liệu bên ngoài.
    • An toàn hơn trong các mã nguồn TypeScript hiện đại.
typescript Copy
// Phản hồi API - không an toàn
function fetchData(): any {
  return { name: "Alice", age: 25 };
}
let dataAny = fetchData();
console.log(dataAny.name.toUpperCase()); // ❌ Nguy hiểm nếu 'name' không phải là chuỗi

// Phản hồi API - an toàn
function fetchDataSafe(): unknown {
  return { name: "Alice", age: 25 };
}
let dataUnknown = fetchDataSafe();
if (typeof dataUnknown === "object" && dataUnknown !== null && "name" in dataUnknown) {
  console.log((dataUnknown as { name: string }).name.toUpperCase()); // ✅ An toàn
}

5. Dễ Sai Lầm So Với An Toàn

  • any: Dễ gây ra sự cố thời gian chạy.
  • unknown: Trình biên dịch đảm bảo an toàn.
typescript Copy
let valueAny: any = 42;
valueAny.toUpperCase(); // ❌ Biên dịch, 💥 lỗi thời gian chạy

let valueUnknown: unknown = 42;
// ❌ valueUnknown.toUpperCase(); (lỗi thời gian biên dịch, an toàn)

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

  • 🚫 Tránh sử dụng any khi có thể – nó làm yếu đi lợi ích cốt lõi của TypeScript.
  • Sử dụng unknown cho dữ liệu động (API, JSON, đầu vào của người dùng).
  • 🔍 Thu hẹp unknown với các bảo vệ kiểu trước khi sử dụng.
typescript Copy
function isString(value: unknown): value is string {
  return typeof value === "string";
}

let input: unknown = "Xin chào";
if (isString(input)) {
  console.log(input.toUpperCase()); // ✅ An toàn
}

Bảng Tóm Tắt

Tính Năng any unknown
An Toàn Kiểu ❌ Không có, vô hiệu hóa kiểm tra kiểu ✅ Bắt buộc kiểm tra trước khi sử dụng
Các Thao Tác Cho Phép Bất kỳ thao tác nào Chỉ sau khi đã thu hẹp
Gán Có thể gán cho/từ bất kỳ thứ gì Chỉ có thể gán cho any/unknown
Trường Hợp Sử Dụng Mã cũ, di chuyển, hack nhanh Xử lý an toàn dữ liệu bên ngoài
Rủi Ro Thời Gian Chạy Cao Thấp (với kiểm tra)

Kết Luận

  • any: Là một con dao hai lưỡi. Tiện lợi, nhưng nguy hiểm nếu lạm dụng. Tốt nhất nên giữ cho di chuyển mã cũ hoặc sửa chữa nhanh.
  • unknown: Là sự thay thế an toàn và hiện đại. Nó cho phép bạn xử lý các giá trị động mà không hy sinh an toàn kiểu.

👉 Nguyên Tắc Chung:

  • Hãy sử dụng unknown trong các dự án TypeScript hiện đại.
  • Chỉ sử dụng any khi bạn thực sự cần phải bỏ qua hệ thống kiểu.

Bằng cách ưu tiên unknown hơn any, bạn sẽ viết mã TypeScript an toàn hơn, dễ dự đoán hơn, và dễ bảo trì hơn.


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