Làm Chủ Strict Mode Trong TypeScript — Biến Trình Biên Dịch Thành "Code Reviewer"
Bạn viết TypeScript nhưng vẫn để trình biên dịch dễ dãi như JavaScript? Vậy đã đến lúc bạn làm quen với Strict Mode — công cụ giúp TypeScript phát huy tối đa sức mạnh kiểm tra kiểu tĩnh, bắt lỗi sớm và hướng bạn đến một codebase sạch, rõ ràng, và cực kỳ đáng tin cậy.
Bật strict mode
Chỉ cần thêm "strict": true
vào tsconfig.json
, bạn đang bật một gói các kiểm tra cực kỳ nghiêm ngặt:
{ "compilerOptions": { "strict": true }
}
Việc này tương đương với bật hàng loạt tùy chọn nhỏ hơn. Cùng tìm hiểu từng cái:
1. strictNullChecks
Bật lên: bạn không thể gán null
hoặc undefined
cho một biến nếu bạn không cho phép điều đó.
let name: string = null; // ❌ Lỗi nếu strictNullChecks = true
Muốn cho phép? Hãy rõ ràng:
let name: string | null = null;
Vì sao quan trọng?
80% lỗi runtime của JavaScript là do undefined is not a function
, null has no property...
. Tùy chọn này cắt luôn mầm mống đó.
2. noImplicitAny
TypeScript cho phép suy luận kiểu, nhưng đôi khi nó “bó tay” và fallback về any
. Tùy chọn này không cho phép điều đó xảy ra trong im lặng.
function log(message) { console.log(message);
}
// 👆 message ngầm định là `any`
Với noImplicitAny: true
, bạn bắt buộc phải khai báo kiểu rõ ràng:
function log(message: string) { console.log(message);
}
3. strictFunctionTypes
Tùy chọn này làm việc với hệ thống kiểm tra tương thích hàm.
Ví dụ:
type A = (value: number) => void;
type B = (value: number | string) => void; let fn: B = (val) => console.log(val); let f: A = fn; // ❌ strictFunctionTypes: không an toàn
Nó giúp đảm bảo bạn không gán một function "có thể xử lý nhiều hơn" cho một function "xử lý ít hơn", tránh lỗi logic.
4. strictBindCallApply
Khi bạn dùng .bind
, .call
, .apply
— TypeScript mặc định không kiểm tra kỹ lắm. Tùy chọn này buộc bạn dùng đúng kiểu đối số.
function greet(name: string) { return `Hi ${name}`;
} greet.call(null, 123); // ❌ Số không phải string
5. strictPropertyInitialization
Yêu cầu bạn phải khởi tạo tất cả property trong class trước khi dùng, hoặc rõ ràng đánh dấu là có thể undefined
.
class User { name: string; // ❌ Không được khởi tạo constructor() {}
}
Cách fix:
class User { name: string; constructor() { this.name = "Anonymous"; }
}
Hoặc nếu bạn thực sự biết mình đang làm gì:
class User { name!: string; // Dùng `!` để nói “Tôi sẽ tự khởi tạo sau”
}
6. noImplicitThis
Ngăn bạn dùng this
trong function mà TypeScript không thể suy luận kiểu của this
.
function show() { console.log(this.name); // ❌ this là gì?
}
Giải pháp:
- Dùng function trong context class
- Hoặc dùng arrow function để giữ
this
:
const show = () => { console.log(this.name);
};
7. alwaysStrict
Tự động chèn "use strict"
vào tất cả file JS output. Điều này giúp môi trường runtime của bạn tránh những hành vi kỳ lạ của JS kiểu cổ.
Tổng kết
Tùy chọn | Ý nghĩa |
---|---|
strictNullChecks |
Cấm null /undefined nếu không khai báo |
noImplicitAny |
Bắt khai báo rõ ràng kiểu nếu không suy luận được |
strictFunctionTypes |
Kiểm tra tương thích hàm chặt chẽ hơn |
strictBindCallApply |
Bắt lỗi khi dùng bind/call/apply sai kiểu |
strictPropertyInitialization |
Bắt buộc khởi tạo property class |
noImplicitThis |
Không cho phép this mơ hồ |
alwaysStrict |
JS output luôn ở chế độ "use strict" |
Lời khuyên từ người từng "gãy"
- Dự án mới? Bật
strict
ngay từ đầu. - Dự án cũ? Bật từng phần, sửa dần.
- Làm frontend hay backend đều nên bật.
Code nghiêm ngặt là code đáng tin. Strict mode không phải gò bó bạn — nó giúp bạn an toàn hơn và ngủ ngon hơn.
Happy strict coding! 🚀