Ba kiểu ở ba vị trí đối lập nhau trong hệ thống kiểu.
typescript
// any — TẮT kiểm tra kiểu. Gán đi đâu cũng được, gọi gì cũng được.
let a: any = 'text'
a.toFixed(2) // không báo lỗi lúc biên dịch, NỔ lúc chạy
// unknown — nhận mọi giá trị, nhưng PHẢI thu hẹp trước khi dùng
let u: unknown = JSON.parse(raw)
u.toFixed(2) // Lỗi: 'u' is of type 'unknown'
if (typeof u === 'number') u.toFixed(2) // ok sau khi thu hẹp
// never — kiểu KHÔNG BAO GIỜ có giá trị
function fail(msg: string): never { throw new Error(msg) }| Gán giá trị vào | Gán ra biến khác | An toàn | |
|---|---|---|---|
any | mọi thứ | mọi thứ | không |
unknown | mọi thứ | chỉ sau khi thu hẹp | có |
never | không gì | mọi thứ | — |
Công dụng thực tế của never — kiểm tra vét cạn, để thêm một nhánh mới mà quên xử lý là compiler báo ngay:
typescript
type Status = 'draft' | 'published' | 'archived'
function label(s: Status): string {
switch (s) {
case 'draft': return 'Nháp'
case 'published': return 'Đã đăng'
case 'archived': return 'Lưu trữ'
default: {
const _exhaustive: never = s // thêm status mới → lỗi biên dịch tại đây
return _exhaustive
}
}
}Chốt: dữ liệu từ bên ngoài (API, JSON.parse, localStorage) nên khai unknown rồi kiểm tra, không dùng any. any chỉ chấp nhận được như bước tạm khi chuyển JS sang TS, và nên bật noImplicitAny để nó không lọt vào âm thầm.