typescript

tsconfig.json Strict Mode

TypeScript strict mode configuration with all safety checks enabled, path aliases, and recommended compiler options.

Overview

A TypeScript configuration with strict mode fully enabled. This catches the most bugs at compile time by enabling all type-checking flags, including strict null checks, no implicit any, and strict function types. Recommended for all new projects.

Configuration

// tsconfig.json
{
  "compilerOptions": {
    // ── Language & Environment ──
    "target": "ES2022",                // Modern JS output (top-level await, etc.)
    "lib": ["ES2023"],                 // Available type definitions
    "module": "NodeNext",              // Node.js ESM module system
    "moduleResolution": "NodeNext",    // Resolve imports like Node.js does

    // ── Strict Type Checking (all flags) ──
    "strict": true,                    // Enables ALL strict flags below:
    // "strictNullChecks": true,       //   null/undefined not assignable to other types
    // "strictFunctionTypes": true,    //   Stricter function parameter checking
    // "strictBindCallApply": true,    //   Check bind, call, apply arguments
    // "strictPropertyInitialization": true, // Class properties must be initialized
    // "noImplicitAny": true,          //   Error on expressions with implied 'any'
    // "noImplicitThis": true,         //   Error on 'this' with implied 'any'
    // "alwaysStrict": true,           //   Emit "use strict" in every file
    // "useUnknownInCatchVariables": true, // catch(e) types as 'unknown' not 'any'

    // ── Additional Safety Checks ──
    "noUncheckedIndexedAccess": true,  // Array/object index access returns T | undefined
    "noImplicitReturns": true,         // Error if not all code paths return
    "noFallthroughCasesInSwitch": true,// Error on switch fallthrough
    "noImplicitOverride": true,        // Require 'override' keyword on class methods
    "noPropertyAccessFromIndexSignature": true, // Use bracket notation for index sigs
    "exactOptionalPropertyTypes": true,// Differentiate between undefined and missing
    "forceConsistentCasingInFileNames": true, // Prevent case-sensitivity issues

    // ── Module & Import ──
    "esModuleInterop": true,           // Allow default imports from CJS modules
    "isolatedModules": true,           // Ensure each file can be transpiled alone
    "verbatimModuleSyntax": true,      // Enforce import type for type-only imports
    "resolveJsonModule": true,         // Allow importing .json files

    // ── Path Aliases ──
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],              // Import from @/components/Button
      "@lib/*": ["./src/lib/*"],       // Import from @lib/utils
      "@types/*": ["./src/types/*"]    // Import from @types/user
    },

    // ── Output ──
    "outDir": "dist",                  // Compiled output directory
    "rootDir": "src",                  // Source files root
    "declaration": true,               // Generate .d.ts declaration files
    "declarationMap": true,            // Source maps for declarations
    "sourceMap": true,                 // Generate source maps
    "removeComments": false,           // Keep comments in output

    // ── Build Performance ──
    "incremental": true,               // Faster rebuilds with .tsbuildinfo
    "tsBuildInfoFile": ".tsbuildinfo", // Build info cache file
    "skipLibCheck": true               // Skip type checking of .d.ts files
  },

  "include": ["src/**/*"],            // Files to compile
  "exclude": [
    "node_modules",
    "dist",
    "**/*.test.ts",                    // Exclude test files from build
    "**/*.spec.ts"
  ]
}

Key Options Explained

  • strict: true — Umbrella flag that enables 8 individual strict checks. As TypeScript adds new strict flags in future versions, strict: true will automatically include them.
  • noUncheckedIndexedAccess — Makes array[0] return T | undefined instead of T. Prevents runtime errors when accessing out-of-bounds indices.
  • exactOptionalPropertyTypes — Distinguishes between a property that is undefined and a property that is missing entirely. More precise but requires explicit handling.
  • verbatimModuleSyntax — Requires import type { Foo } for type-only imports instead of import { Foo }. Helps bundlers with tree-shaking.
  • isolatedModules — Ensures compatibility with single-file transpilers like esbuild, SWC, and Babel that don’t have cross-file type information.
  • skipLibCheck — Skips type checking of .d.ts files in node_modules. Significantly speeds up compilation without reducing safety of your own code.

Common Modifications

  • For libraries: Add "declaration": true and "declarationDir": "types" to generate type definitions for consumers.
  • DOM projects: Add "DOM", "DOM.Iterable" to the lib array for browser APIs.
  • Bundler module resolution: Use "moduleResolution": "Bundler" if using Vite, Webpack, or esbuild instead of Node.js directly.
  • Monorepo references: Add "references": [{ "path": "../shared" }] and "composite": true for project references.
  • Relax for migration: Temporarily set "strict": false and enable individual flags one at a time when migrating from JavaScript.