strict: true is shorthand for enabling a whole family of individual compiler flags at once, including noImplicitAny (no silently-typed any parameters), strictNullChecks (null and undefined aren't assignable to other types unless explicitly included), and strictFunctionTypes (stricter checking of function parameter compatibility). Each flag can also be enabled individually for a gradual, incremental migration. TypeScript 6.0 (2026) made strict the default for new projects, reflecting years of accumulated community consensus that it catches real bugs.
strictNullChecks: the single most impactful flag
Without this flag, null and undefined are silently assignable to any type — a real, common source of runtime crashes that TypeScript is supposed to catch at compile time in the first place.
// with strictNullChecks: true
function greet(name: string) {
return name.toUpperCase();
}
let userName: string = null; // COMPILE ERROR: null is not assignable to string
greet(userName); // caught before this even runs
// to allow null explicitly, opt in with a union:
let maybeName: string | null = null; // fine — explicitly statednoImplicitAny: no silent any
Without this flag, an untyped parameter silently becomes any, defeating the entire point of using TypeScript for that parameter without a visible warning anywhere.
// with noImplicitAny: true
function double(x) { // COMPILE ERROR: parameter 'x' implicitly has an 'any' type
return x * 2;
}
function doubleFixed(x: number) { // explicit type required
return x * 2;
}Migrating an existing codebase incrementally
Turning on the full strict bundle at once on an existing large codebase can surface hundreds of errors instantly; enabling individual flags one at a time — typically starting with strictNullChecks, since it usually finds the most real bugs — lets a team migrate gradually instead of all at once.
{
"compilerOptions": {
"strict": false,
"strictNullChecks": true, // enable one flag at a time during migration
"noImplicitAny": true
}
}