strict
Turns on every strict type-checking flag at once, including ones added in future releases.
"strict": boolean // Default: true- Added in TypeScript 2.3
Parameters
| Parameter | Type | Description |
|---|---|---|
$strictoptional | boolean= true | Enables the whole strict-mode family of type-checking flags. Individual family members set explicitly in the same tsconfig override it. |
Errors
Nothing at runtime; it only changes which type errors tsc reports at compile time.
Changelog
- PHP 2.6strictFunctionTypes joined the family.
- PHP 2.7strictPropertyInitialization joined the family.
- PHP 3.2strictBindCallApply joined the family.
- PHP 4.4useUnknownInCatchVariables joined the family, so catch clause variables became unknown instead of any.
- PHP 5.6strictBuiltinIteratorReturn joined the family, giving built-in iterators a TReturn of undefined instead of any.
strict is not a check of its own. It is an umbrella that switches on every member of the strict mode family, and it keeps doing so for members added in later versions of TypeScript.
What it turns on
alwaysStrictstrictNullChecksstrictBindCallApplystrictBuiltinIteratorReturnstrictFunctionTypesstrictPropertyInitializationnoImplicitAnynoImplicitThisuseUnknownInCatchVariables
Switching one back off
Set the individual flag after — or before, order does not matter — strict. The explicit value wins:
{ "compilerOptions": { "strict": true, "strictPropertyInitialization": false } }That is the supported way to adopt strict mode on a large codebase: enable the umbrella, disable the one or two checks that produce thousands of errors, and delete those lines one at a time.
What trips people up
Because the family grows, a TypeScript upgrade can introduce new errors in code you did not touch. That is documented and intentional — each new check gets its own flag so you can opt out. It also does not cover everything with "strict" in the name: exactOptionalPropertyTypes, noUncheckedIndexedAccess and noImplicitOverride are separate opt-ins.
Example
// tsconfig.json -> { "compilerOptions": { "strict": true } }
interface Job {
name: string;
retries: number;
}
// Under strict, this parameter must be annotated (noImplicitAny),
// and `job` cannot be null or undefined (strictNullChecks).
function describe(job: Job): string {
return job.name + " retries " + job.retries + "x";
}
const uploader: Job = { name: "uploader", retries: 3 };
console.log(describe(uploader));
// -> uploader retries 3xWhen to use it
- Starting a new project with the strongest checks the compiler offers
- Adopting strict mode gradually by disabling one family member at a time
- Auditing whether a dependency's tsconfig actually type-checks null
Frequently asked questions
What does strict actually enable in tsconfig?
It enables alwaysStrict, strictNullChecks, strictBindCallApply, strictBuiltinIteratorReturn, strictFunctionTypes, strictPropertyInitialization, noImplicitAny, noImplicitThis and useUnknownInCatchVariables. Future TypeScript versions may add more members to that list.
Can I use strict but turn off one of its checks?
Yes — set the individual flag to false in the same compilerOptions block, for example "strict": true with "strictPropertyInitialization": false. The explicit flag always wins over the umbrella, regardless of the order the keys appear in.
Why did my code break after upgrading TypeScript with strict on?
Because new checks are added to the strict family over time — useUnknownInCatchVariables in 4.4 and strictBuiltinIteratorReturn in 5.6, for instance. Each one has its own flag, so you can set that flag to false to restore the old behaviour while you fix the errors.
More examples
Disabling one family member
strictPropertyInitialization: false survives even though strict is true, so the uninitialised userId compiles. The log shows what it actually holds at runtime: undefined, exactly the hole the check exists to prevent.
// tsconfig.json
// {
// "compilerOptions": {
// "strict": true,
// "strictPropertyInitialization": false
// }
// }
class Session {
userId: string; // no error: the field check is off
createdBy = "system";
}
const s = new Session();
console.log(s.userId, s.createdBy);
// -> undefined systemWhat strict rejects that loose mode accepts
Type stripping removes the annotations, so both lines still run and print 10 and null. The point is what tsc says beforehand: without strict, a null string and an implicitly any parameter ship silently.
// With "strict": false all four of these compile.
// With "strict": true tsc reports the errors in the comments.
function len(s) { // 7006: parameter implicitly has an 'any' type
return s.length;
}
const name: string = null; // 2322: 'null' is not assignable to 'string'
console.log(len("typescript")); // 10
console.log(name); // null
console.log(typeof name); // object
Discussion