/config/typescript/tsconfig-strict
tsconfig strict: what "strict": true enables
- tool
- TypeScript
- file
- tsconfig.json
- key
- compilerOptions.strict
- type
- boolean
- default
- true since TypeScript 6.0, false before
"strict": true in compilerOptions enables every option of the strict family at once: noImplicitAny, strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitThis, useUnknownInCatchVariables, alwaysStrict and, since 5.6, strictBuiltinIteratorReturn. strict is on by default since TypeScript 6.0 and was off before. New strict options added by future TypeScript releases are included automatically. Any single option can still be turned off after strict ("strict": true, "noImplicitAny": false).
What strict catches
npm init -y >/dev/null
npm install --silent --no-audit --no-fund typescript@6 >/dev/null 2>&1
cat > app.ts <<'EOF'
function len(s) { return s.length; }
const el: HTMLElement | null = null;
const user = { name: "Ada" as string | undefined };
console.log(len("x"), el.id, user.name.toUpperCase());
EOF
echo '--- strict false'
npx tsc --noEmit --strict false --lib es2022,dom app.ts && echo "no errors"
echo '--- strict true'
npx tsc --noEmit --strict true --lib es2022,dom app.tsOutput · exit 2
--- strict false no errors --- strict true app.ts(1,14): error TS7006: Parameter 's' implicitly has an 'any' type. app.ts(4,23): error TS18047: 'el' is possibly 'null'. app.ts(4,30): error TS18048: 'user.name' is possibly 'undefined'.
With strict off the file compiles, and all three bugs would only show at runtime. With strict on, noImplicitAny flags the untyped parameter and strictNullChecks flags both possibly-null accesses.
The options it enables
| Option | What it checks |
|---|---|
| noImplicitAny | Parameters and variables whose type would silently become any |
| strictNullChecks | null and undefined are separate types and must be handled before use |
| strictFunctionTypes | Function parameters are checked contravariantly |
| strictBindCallApply | Arguments of bind, call and apply are type-checked |
| strictPropertyInitialization | Class properties must be initialised in the constructor (needs strictNullChecks) |
| noImplicitThis | this with an implicit any type is an error |
| useUnknownInCatchVariables | catch (e) gives e the type unknown instead of any (4.4+) |
| alwaysStrict | Emits "use strict" and parses files in strict mode |
| strictBuiltinIteratorReturn | Built-in iterators return undefined instead of any when done (5.6+) |
Default value
npm init -y >/dev/null
npm install --silent --no-audit --no-fund typescript@6 >/dev/null 2>&1
echo 'function len(s) { return s.length; } console.log(len("x"));' > app.ts
echo '{ "compilerOptions": { "noEmit": true }, "files": ["app.ts"] }' > tsconfig.json
npx tsc --version
npx tsc; echo "exit status: $?"Output
Version 6.0.3 app.ts(1,14): error TS7006: Parameter 's' implicitly has an 'any' type. exit status: 2
The tsconfig.json above does not mention strict, yet TypeScript 6 reports the implicit any: strict defaults to true since TypeScript 6.0. Releases before 6.0 defaulted it to false, so older projects that never set it can show many new errors after an upgrade. Set it explicitly in every project so the behaviour does not depend on the compiler version.
Adopting strict in an existing project
{
"compilerOptions": {
"strict": true,
"strictPropertyInitialization": false
}
}Turn on strict, disable the options that produce the most errors, fix the remaining ones, then remove the exceptions one at a time.