The strict flag is a bundle of checks, not a single one. Turning it on catches nullability, implicit any and function-assignment mistakes, but a few high-value checks live outside the bundle and must be enabled separately.
Before you start
You should be comfortable with a tsconfig.json and have some experience fixing type errors. This article explains what the main flags do and how to adopt them without a huge migration.
Step-by-step walkthrough
Step 1: Use strict as the baseline
"strict": true enables strictNullChecks, noImplicitAny, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitThis and alwaysStrict. Together they make null and undefined distinct from other types and require explicit parameter types, which is where most of the value comes from.
Step 2: Add the extras that strict leaves out
noUncheckedIndexedAccess makes every index and array lookup possibly undefined. exactOptionalPropertyTypes stops undefined from being assigned to an optional property unless declared. noImplicitOverride and noFallthroughCasesInSwitch catch smaller mistakes. These are not in strict because they are noisier.
Step 3: Adopt incrementally without losing coverage
For an existing codebase, turn on strict and fix errors file by file, or start with the highest-value flag (strictNullChecks) and widen over time. Avoid scattering any to silence errors, which defeats the purpose; use unknown at boundaries and narrow.
Worked scenario
The config shows the bundle plus the two extras worth adding.
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
}Walk through the example
With strict on, function f(x) {} now errors because x is implicitly any, and a possibly-null value cannot be used without a check. Adding noUncheckedIndexedAccess means items[0] is T | undefined, so you handle the empty case explicitly. exactOptionalPropertyTypes makes { name: undefined } invalid for { name?: string } unless undefined is allowed.
Common mistake
Assuming strict covers index access; it does not, so arr[0] is typed T and a runtime undefined sneaks through. Another mistake is enabling exactOptionalPropertyTypes without realising it changes the meaning of optional properties, breaking code that passes explicit undefined.
Verify the behavior
Introduce one error per flag and confirm each is reported: an implicit any parameter, a possibly-null dereference, an unchecked index result, and an explicit undefined for an exact optional property. Then fix each minimally and confirm the file compiles, which demonstrates what each flag actually enforces.
Interview exercise
A team enables strict but still ships crashes from array[0] being undefined. Which flag is missing, and what is the fix?
Answer and reasoning
noUncheckedIndexedAccess is missing: without it, index and array access is typed as if a value always exists. Enable it and handle the undefined case, usually with an early return, a default, or a length check. This converts a class of runtime crashes into compile-time errors without changing runtime behavior.
Continue learning
See the flow consequences in strict null flow and optional property presence. Read the TypeScript tsconfig reference and try the TypeScript MCQs.