TypeScript Strict tsconfig Template
A maximally strict TypeScript configuration template that catches the most bugs at compile time — with explanations for every option.
Description
A production-ready tsconfig.json with every strict option enabled and documented. Each flag includes a brief explanation of what it catches.
The Config
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
// ── Target & Module ──
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2022"],
"esModuleInterop": true,
// ── Output ──
"outDir": "dist",
"rootDir": "src",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
// ── Strict Mode (all flags) ──
"strict": true,
// Includes:
// "strictNullChecks": true — null/undefined are distinct types
// "strictFunctionTypes": true — contravariant function parameter checks
// "strictBindCallApply": true — type-check bind/call/apply
// "strictPropertyInitialization": true — class props must be initialized
// "noImplicitAny": true — no implicit 'any' types
// "noImplicitThis": true — 'this' must have an explicit type
// "alwaysStrict": true — emit "use strict" in every file
// "useUnknownInCatchVariables": true — catch variables are 'unknown', not 'any'
// ── Additional Strictness ──
"noUncheckedIndexedAccess": true,
// Array/object index access returns T | undefined (catches out-of-bounds)
"exactOptionalPropertyTypes": true,
// Distinguishes between { x?: string } (missing) and { x: undefined }
"noPropertyAccessFromIndexSignature": true,
// Forces bracket notation for index signatures: obj["key"] not obj.key
"noFallthroughCasesInSwitch": true,
// Errors on switch case fall-through without break
// ── Unused Code Detection ──
"noUnusedLocals": true,
"noUnusedParameters": true,
// Prefix unused params with _ to acknowledge: (_req, res) =>
// ── Import Hygiene ──
"verbatimModuleSyntax": true,
// Forces explicit type imports: import type { Foo } from './foo'
"resolveJsonModule": true,
"isolatedModules": true,
// ── Path Aliases ──
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@domain/*": ["src/domain/*"],
"@infra/*": ["src/infrastructure/*"]
},
// ── Build Performance ──
"incremental": true,
"tsBuildInfoFile": "./dist/.tsbuildinfo",
"skipLibCheck": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
}
What Each Strict Flag Catches
| Flag | Catches |
|---|---|
strictNullChecks | Cannot read property of null/undefined |
noImplicitAny | Accidentally untyped parameters |
noUncheckedIndexedAccess | Array out-of-bounds access |
exactOptionalPropertyTypes | undefined vs missing property confusion |
noUnusedLocals | Dead variables sitting in code |
verbatimModuleSyntax | Type imports erased at runtime causing issues |
Usage
# Check types
npx tsc --noEmit
# Build
npx tsc
# Watch mode
npx tsc --watch