Bốn từ khóa này đều xuất hiện nhiều khi làm việc với TypeScript, cùng bắt tay vào phân biệt nhé ✌️
Kiểu dữ liệu: unknown và any
Cả any và unknown đều cho phép bạn gán bất kỳ kiểu dữ liệu nào (chuỗi, số, object, hàm…) cho biến đó. Tuy nhiên, triết lý an toàn của chúng hoàn toàn trái ngược nhau:
any(Buông xuôi): Khi bạn dùngany, TypeScript sẽ tắt toàn bộ cơ chế kiểm tra lỗi. Nó cho phép bạn làm bất cứ điều gì với biến đó (gọi hàm, chấm thuộc tính) mà không hề gạch đỏ. Đây là nguyên nhân lớn nhất gây lỗi sập nguồn đột ngột (Crash) lúc runtime.unknown(Cẩn trọng): Đúng như cái tên “Chưa rõ kiểu”,unknowncho phép bạn bỏ gì vào cũng được, nhưng cấm tuyệt đối không cho bạn đem ra sử dụng trừ khi bạn chứng minh được kiểu dữ liệu của nó thông qua việc kiểm tra (typeof,instanceof).
// Hàm toFixed() để convert 1 số sang 1 string, method này chỉ available cho biến kiểu số
// --- TRƯỜNG HỢP DÙNG ANY ---
let bienAny: any = "Xin chào Linh";
bienAny.toFixed(2);
// TS KHÔNG báo lỗi khi gõ code.
// ❌ Nhưng khi CHẠY chương trình sẽ bị CRASH lập tức vì Chuỗi không có hàm toFixed!
// --- TRƯỜNG HỢP DÙNG UNKNOWN ---
let bienUnknown: unknown = "Xin chào Linh";
// bienUnknown.toFixed(2); // TS GẠCH ĐỎ NGAY: Object is of type 'unknown'.
// CÁCH DÙNG ĐÚNG VỚI UNKNOWN (Phải dùng Type Guard để kiểm tra):
if (typeof bienUnknown === "number") {
bienUnknown.toFixed(2); // Lúc này TS sẽ cho phép chạy vào đây
}
| Tiêu chí | any | unknown |
|---|---|---|
| Nhận mọi giá trị | Có | Có |
| Dùng ngay mà chưa kiểm tra | Có | Không |
| Khả năng che giấu lỗi | Cao | Thấp hơn |
| Nên dùng cho dữ liệu chưa tin cậy | Không nên | Nên dùng rồi thu hẹp kiểu |
Giá trị của biến: null và undefined
Cả hai đều đại diện cho việc “không có dữ liệu”, nhưng ngữ cảnh sinh ra của chúng khác nhau:
undefined(Chưa có giá trị): Là trạng thái biến đã được khai báo nhưng chưa được gán giá trị, hoặc một thuộc tính không tồn tại trong object. Trạng thái này thường do hệ thống tự động gán.null(Giá trị trống rỗng cố ý): Là một giá trị mà lập trình viên chủ động gán để biểu thị rằng biến này hiện tại đang trống rỗng, không chứa đối tượng nào cả.
| Giá trị | Ý nghĩa thường dùng | Ví dụ |
|---|---|---|
undefined | Chưa được gán hoặc thuộc tính không tồn tại | Người dùng không gửi trường phone |
null | Chủ động biểu diễn “không có giá trị” | API trả avatar: null |
// 1. Hệ thống tự gán undefined
let userName: string;
console.log(userName); // Kết quả: undefined (Vì đã gán gì đâu)
const hocSinh = { ten: "An" };
console.log(hocSinh.tuoi); // Kết quả: undefined (Vì thuộc tính 'tuoi' không tồn tại)
// 2. Lập trình viên chủ động gán null
let currentUser: string | null = "Linh";
// Khi user đăng xuất, ta chủ động xóa dữ liệu bằng null
currentUser = null;
// 3. So sánh bằng dấu == và ===
console.log(null == undefined); // true (So sánh lỏng lẻo: đều là "không có gì")
console.log(null === undefined); // false (So sánh nghiêm ngặt: khác nhau hoàn toàn)
Kinh nghiệm xương máu khi viết Playwright / TypeScript
- Hãy né xa
any: Khi viết hàm nhận dữ liệu động (như đọc file JSON hoặc response từ API), hãy dùngunknown. Sau đó dùngif (typeof ...)để ép kiểu, code của bạn sẽ không bao giờ bị lỗi ngầm bất ngờ. - Bật
strictNullChecks: true: Trong file cấu hìnhtsconfig.json, hãy chắc chắn đã bật cờ này. TypeScript sẽ bắt bạn phải kiểm tra xem một phần tử (Locator) có bịnullhoặcundefinedhay không trước khi bạn thực hiện các lệnh.click()hoặc.fill()trong Playwright, giúp bài test của bạn chạy cực kỳ ổn định trên CI/CD.




