Master TypeScript Strict Mode Best Practices [Reduce Runtime Errors]

Làm Chủ TypeScript Strict Mode Best Practices [Giảm Lỗi Runtime]

Master TypeScript Strict Mode Best Practices [Reduce Runtime Errors]

Bạn đã bao giờ tự tin vỗ ngực "code viết bằng TypeScript an toàn lắm" rồi lại muối mặt khi ứng dụng của mình "toang" giữa runtime vì một lỗi cannot read property 'length' of null chưa? Mình thì bị rồi, và cảm giác lúc đó thực sự tồi tệ. Hoá ra, chỉ khai báo vài cái type cơ bản là chưa đủ. "Trùm cuối" thực sự giúp giảm thiểu lỗi runtime, thứ bảo vệ bạn khỏi những pha thức dậy lúc 3 giờ sáng để fix bug, chính là Strict Mode. Đây không phải là một tính năng "có thì tốt", mà là một bộ quy tắc bắt buộc phải bật để đảm bảo chất lượng cho mã nguồn. Nếu bạn là người mới chuyển sang ngôn ngữ này, việc Học TypeScript từ đầu cho JavaScript developer luôn đi kèm với lời khuyên xương máu: hãy bật chế độ nghiêm ngặt ngay từ ngày đầu tiên.

Why is enabling "strict: true" almost mandatory for every TypeScript project?

Enabling "strict: true" is required because it switches TypeScript from loose testing mode to comprehensive protection, helping to detect runtime errors early on right from the moment the code is written.

Tại Phạm Hải, chúng mình luôn coi TypeScript strict mode cho dự án mới là tiêu chuẩn mặc định không thể thương lượng. Thực tế, theo bản cập nhật TypeScript 6.0 RC mới nhất ra mắt vào tháng 3/2026, Microsoft đã chính thức đặt strict: true làm cấu hình mặc định. Điều này minh chứng rõ ràng rằng lợi ích strict mode TypeScript là cực kỳ to lớn đối với các ứng dụng web quy mô lớn. Chế độ này không sinh ra để làm khó bạn, mà để bảo vệ bạn khỏi chính những sai sót logic của bản thân.

Ngăn chặn "quả bom nổ chậm" mang tên nullundefined

Nhiều bạn mới học thường thắc mắc strictNullChecks là gì? Nói một cách đơn giản, đây là tính năng ngăn chặn việc gán null hoặc undefined cho các kiểu dữ liệu khác một cách tuỳ tiện. Trong môi trường phát triển tích hợp (IDE), trình biên dịch TypeScript sẽ ngay lập tức gạch chân đỏ chót nếu bạn cố truy cập một thuộc tính của object có nguy cơ bị null.

Rigorously checking for null, undefined helps you avoid up to 90% of silly errors that crash the application. Instead of letting the code run and then crashing, errors will be stopped right from the moment you are typing.

Bịt các lỗ hổng từ kiểu any ngầm định

Vậy còn noImplicitAny là gì? Cờ này cấm bạn khai báo biến hoặc tham số hàm mà không chỉ định kiểu rõ ràng, khiến TypeScript phải tự đoán và gán kiểu any. Việc lạm dụng any sẽ phá vỡ hoàn toàn an toàn kiểu (type safety), biến TypeScript của bạn thoái hóa thành JavaScript thông thường.

By tightening this rule, you are forced to clearly define data structures for every information flow. By the way, if you are wondering how to define data structures correctly, please see the article Interface vs Type TypeScript to optimize the declaration.

Make sure to initialize values ​​for class properties (strictPropertyInitialization)

Lỗi quên khởi tạo giá trị cho class property rất phổ biến trong phát triển full-stack với các framework hướng đối tượng. Cờ strictPropertyInitialization buộc bạn phải gán giá trị mặc định hoặc khởi tạo chúng ngay trong constructor.

This regulation helps application architecture become much more solid. You will no longer encounter the situation where an object is successfully created, but the data inside is empty and causes chain errors in other modules.

Enhances safety and clarity across the entire codebase

Tại sao nên dùng TypeScript strict mode? Câu trả lời cốt lõi là vì nó trực tiếp nâng cao chất lượng mã nguồnkhả năng bảo trì mã. Khi mọi type đều rõ ràng và được kiểm chứng, việc tái cấu trúc an toàn (safe refactoring) trở nên dễ thở hơn bao giờ hết.

You can confidently rename variables and modify complex logic without fear of damaging other parts of the system. This is the golden key to maintaining programmer productivity over a multi-year project.

Complete information about flags in Strict Mode and how they "save" you

Strict Mode includes a set of flags such as strictNullChecks, noImplicitAny, strictFunctionTypes... to help tighten type checking rules in the tsconfig.json file.

To configure TypeScript strict mode correctly, you need to understand each "weapon" in this security arsenal. Below is a list of core TypeScript strict mode flags and how they operate.

strict: true - Bật tất cả chỉ với một dòng lệnh

Khi bạn set "strict": true trong file tsconfig.json, bạn đang đồng thời kích hoạt toàn bộ các tùy chọn strict mode trong tsconfig. Đây là cách giảm lỗi runtime trong TypeScript nhanh nhất, toàn diện nhất và được khuyến nghị sử dụng rộng rãi nhất.

For easy visualization, you can see the test level comparison table below:

Check feature Default mode (Old) Khi bật strict: true
Check for Null/Undefined Ignore it, it's easy to cause errors Report compile time error
Kiểu ngầm định (any) Accept easily Mandatory clear declaration
Bind function parameters Loose Contravariant

strictNullChecks - "Vệ sĩ" chống lại null/undefined

Như mình đã nhấn mạnh, đây là cờ quan trọng nhất. Strict mode TypeScript giúp ngăn lỗi runtime như thế nào? Chính là nhờ việc nó ép bạn phải viết các đoạn code an toàn như if (value !== null) trước khi sử dụng biến đó. Điều này đặc biệt cứu cánh khi bạn làm việc với DOM element hoặc gọi API trả về dữ liệu không chắc chắn.

noImplicitAny - Ép bạn phải tường minh về kiểu dữ liệu

This flag completely eliminates potential compile-time errors due to missing data types. The TypeScript compiler will "scream" at you if a function parameter is not explicitly typed. It forces your team to maintain disciplined style consistency across the entire project.

strictFunctionTypes - Siết chặt kiểu của tham số hàm

The strictFunctionTypes flag ensures that function parameters are checked strictly against the contravariant principle. If you pass an ill-formed callback function into another function, TypeScript will block it immediately. To gain a deeper understanding of how to pass types flexibly yet safely through complex functions, you can refer to the article TypeScript Generics with easy-to-understand explanations with examples.

strictBindCallApply - Đảm bảo an toàn khi dùng .bind, .call, và .apply

Trong JavaScript truyền thống, các hàm .bind(), .call(), và .apply() rất dễ gây lỗi vì chúng hoàn toàn không kiểm tra tham số truyền vào. Khi bật cờ strictBindCallApply, TypeScript sẽ áp dụng quy tắc kiểm tra kiểu nghiêm ngặt cho cả 3 method trên, đảm bảo bạn không bao giờ truyền thừa hay thiếu đối số.

noImplicitThis - Không cho phép this có kiểu any

Việc đánh mất bối cảnh this là "đặc sản" gây ức chế nhất của JavaScript. Cờ noImplicitThis sẽ báo lỗi ngay nếu từ khóa this bị suy luận ngầm định là any. Điều này cực kỳ quan trọng khi bạn viết các module JavaScript phức tạp, hoặc khi phải làm việc với các class cũ sử dụng nhiều callback.

useUnknownInCatchVariables - An toàn hơn khi xử lý lỗi trong block catch

Theo mặc định cũ, biến error trong khối catch luôn có kiểu any. Khi bật useUnknownInCatchVariables, biến này sẽ trở thành kiểu unknown. Bạn buộc phải ép kiểu hoặc kiểm tra type (ví dụ: if (error instanceof Error)) trước khi đọc thông báo lỗi. Đây là một best practice tuyệt vời và bắt buộc cho việc xử lý lỗi an toàn.

A "painless" strategy for migrating an existing project to Strict Mode

To apply strict mode to an existing codebase without disruption, you should adopt a partial migration strategy: enable one flag at a time instead of enabling it all at once.

Migrating an existing project to strict mode TypeScript is often described as a nightmare if done incorrectly. With thousands of red errors appearing at the same time, your team will easily become discouraged and give up. At Pham Hai, we always advise customers to apply strict mode TypeScript migration strategy in small steps.

Step 1: Start by enabling each flag one at a time, instead of enabling "strict: true" all at once

Đừng vội vàng sửa file tsconfig.json thành strict: true ngay ngày đầu tiên. Hãy thêm từng cờ riêng lẻ vào cấu hình. Cách tiếp cận này giúp cô lập vấn đề, cho phép bạn tái cấu trúc mã một cách có kiểm soát trên codebase hiện có mà không làm gián đoạn tiến độ ra mắt tính năng mới.

Bước 2: Ưu tiên strictNullChecksnoImplicitAny - hai cờ quan trọng nhất

Đây là hai cờ mang lại giá trị lớn nhất trong việc phòng ngừa lỗi. Hãy bật noImplicitAny trước để fix các type bị thiếu, sau đó mới bật strictNullChecks để xử lý các luồng dữ liệu rỗng. Nếu bạn đang làm frontend, việc áp dụng TypeScript strict mode trong React ở bước này sẽ giúp phát hiện ra vô số props bị thiếu hoặc có nguy cơ null. Bạn có thể xem thêm bài TypeScript với React hướng dẫn tích hợp để thiết lập cấu hình chuẩn xác nhất cho dự án UI của mình.

Bước 3: Dành thời gian sửa các lỗi biên dịch một cách bài bản, đừng dùng // @ts-ignore một cách bừa bãi

Việc lạm dụng các comment như // @ts-ignore hay ép kiểu as any chỉ là cách "giấu rác dưới thảm". Hãy kiên nhẫn sửa lại logic code. Việc áp dụng strict mode TypeScript hiệu quả đòi hỏi sự cam kết nghiêm túc từ toàn bộ đội ngũ phát triển frontend cũng như backend.

Bước 4: Tận dụng Type Guards và kiểu unknown để xử lý các trường hợp phức tạp

Khi gặp dữ liệu từ API trả về không rõ ràng, hãy dùng kiểu unknown kết hợp với type guards thay vì dùng any. Để xác thực dữ liệu runtime một cách an toàn và tự động sinh type chặt chẽ, việc sử dụng các thư viện validation là lựa chọn hoàn hảo. Khám phá ngay Zod validation schema TypeScript để thấy cách công cụ này kết hợp tuyệt vời với Strict Mode như thế nào. Ngoài ra, việc bật thêm cờ noUncheckedIndexedAccess ở giai đoạn cuối cũng giúp kiểm tra các phần tử mảng an toàn hơn rất nhiều.

Quick comparison: TypeScript's Strict Mode and JavaScript's "use strict".

TypeScript strict mode checks static types at compile time to prevent logic errors, while JavaScript's "use strict" changes execution behavior at runtime to avoid implicit syntax errors.

Many developers often confuse these two concepts. Even though they have the same name "strict", they operate in two completely separate stages of the application life cycle.

Different goals: TypeScript focuses on compile-time type safety, JavaScript focuses on runtime behavior

Khi so sánh TypeScript strict mode và JavaScript strict mode, điểm khác biệt lớn nhất nằm ở thời điểm hoạt động. TypeScript sử dụng kiểm tra kiểu tĩnh (static type checking) để bắt lỗi trước khi code thực sự chạy. Ngược lại, chỉ thị use strict của JavaScript (được giới thiệu từ thời ES5) hoạt động ở cấp độ lỗi thời gian chạy, ngăn chặn việc sử dụng các biến chưa khai báo (global variables) hoặc các cú pháp dễ gây nhầm lẫn.

Scope of influence: TypeScript's Strict Mode is much more powerful and comprehensive than JavaScript's "use strict".

JS's "use strict" only addresses a very small group of surface errors. Meanwhile, TypeScript's strict feature (continuously upgraded from TypeScript 2.3 and now the default in version 6.0 in 2026) deeply intervenes in data flow, control flow analysis and performance optimization development. Whether you use TypeScript strict mode in Angular, Vue or Node.js, it serves as the most comprehensive and powerful protection for your codebase.

Enabling Strict Mode in TypeScript is not buying yourself a leash or extra work to do, but is an extremely worthy investment for the future of the project. It's like having a difficult but extremely talented colleague who constantly points out errors and forces you to do it right from the first line of code.

The result of this rigor is that you will have a cleaner, easier to maintain codebase, and most importantly, you will sleep better because you are less likely to wake up in the middle of the night to deal with unnecessary runtime problems. Don't hesitate any longer, make Strict Mode a mandatory standard in all your projects.

Have you braved enabling "strict: true" for your project? Please share your practical experiences or difficulties and "tears" you encountered when migrating to TypeScript strict mode best practices in the comments section below! We really want to hear your story.

Note: The information in this article is for reference only. To get the best advice, please contact us directly for specific advice based on your actual needs.

Categories: Lập Trình Web TypeScript

mrhai

Để lại bình luận