Configuration and Compiler Options

1. tsconfig.json Configuration File

Property Description Example
compilerOptions Main configuration object for compiler settings { "target": "ES2022", "module": "ESNext" }
include Array of file patterns to include in compilation ["src/**/*", "types/**/*"]
exclude Array of file patterns to exclude from compilation ["node_modules", "dist", "**/*.test.ts"]
files Explicit list of files to include (overrides include) ["src/main.ts", "src/types.d.ts"]
extends Inherit configuration from another tsconfig file "./tsconfig.base.json"
references Array of project references for composite projects [{ "path": "./packages/core" }]
watchOptions Configuration for watch mode file watching { "watchFile": "useFsEvents" }
typeAcquisition Control automatic type acquisition for JS projects { "enable": true, "include": ["jquery"] }

Example: Basic tsconfig.json Structure

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "lib": ["ES2022", "DOM"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

// Multi-project setup with extends
// tsconfig.base.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  }
}

// tsconfig.json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": "./src"
  },
  "include": ["src/**/*"]
}

// Node.js project configuration
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "resolveJsonModule": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

2. Compiler Options and Strict Mode Settings

Option Description Value/Example
strict Enable all strict type checking options true (enables all below)
strictNullChecks Prevent null/undefined from being assignable to other types true (included in strict)
strictFunctionTypes Check function parameter types contravariantly true (included in strict)
strictBindCallApply Enable strict checking of bind, call, apply methods true (included in strict)
strictPropertyInitialization Ensure class properties are initialized in constructor true (included in strict)
noImplicitAny Error on expressions and declarations with implied any true (included in strict)
noImplicitThis Error when 'this' expression has implied any type true (included in strict)
alwaysStrict Parse in strict mode and emit "use strict" true (included in strict)
noUnusedLocals Report errors on unused local variables true (not in strict)
noUnusedParameters Report errors on unused function parameters true (not in strict)
noImplicitReturns Report error when not all code paths return a value true (not in strict)
noFallthroughCasesInSwitch Report errors for fallthrough cases in switch true (not in strict)
noUncheckedIndexedAccess Include undefined in index signature results true (not in strict)
noImplicitOverride Ensure overriding members are marked with override true (TypeScript 4.3+)
noPropertyAccessFromIndexSignature Require bracket notation for index signature properties true (TypeScript 4.2+)
allowUnusedLabels Allow unused labels in code false (default)
allowUnreachableCode Allow unreachable code without error false (default)
exactOptionalPropertyTypes Differentiate between undefined and missing properties true (TypeScript 4.4+)

Example: Strict Mode Configuration

// Recommended strict configuration
{
  "compilerOptions": {
    // Enable all strict checks
    "strict": true,
    
    // Additional recommended checks not in strict
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "exactOptionalPropertyTypes": true,
    
    // Disallow unreachable code
    "allowUnusedLabels": false,
    "allowUnreachableCode": false
  }
}

// Impact of strictNullChecks
// With strictNullChecks: false
let name: string = null; // OK
let age: number = undefined; // OK

// With strictNullChecks: true
let name: string = null; // Error
let age: number = undefined; // Error
let name2: string | null = null; // OK
let age2: number | undefined = undefined; // OK

// Impact of noUncheckedIndexedAccess
interface Users {
  [id: string]: { name: string; }
}
const users: Users = {};

// With noUncheckedIndexedAccess: false
const user = users["123"]; // Type: { name: string; }
console.log(user.name); // No error, but could crash

// With noUncheckedIndexedAccess: true
const user2 = users["123"]; // Type: { name: string; } | undefined
console.log(user2.name); // Error: Object is possibly undefined
if (user2) {
  console.log(user2.name); // OK
}

3. Path Mapping and baseUrl Configuration

Option Description Example
baseUrl Base directory for resolving non-relative module names "./src" or "."
paths Map module names to locations relative to baseUrl { "@/*": ["*"], "@components/*": ["components/*"] }
rootDirs List of root folders whose contents are merged at runtime ["src/", "generated/"]
typeRoots Directories containing type definitions ["./node_modules/@types", "./types"]
types Specific type packages to include (limits auto-inclusion) ["node", "jest", "express"]
moduleResolution Strategy for resolving modules: Node, Node16, NodeNext, Classic "Node16" (recommended for Node.js projects)
resolveJsonModule Allow importing .json files as modules true
allowImportingTsExtensions Allow importing .ts files with extension (TS 5.0+) true

Example: Path Mapping Configuration

// tsconfig.json
{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      // Map @ to src root
      "@/*": ["*"],
      
      // Map specific directories
      "@components/*": ["components/*"],
      "@utils/*": ["utils/*"],
      "@services/*": ["services/*"],
      "@types/*": ["types/*"],
      
      // Map to specific files
      "@config": ["config/index.ts"],
      
      // Multiple fallback locations
      "@shared/*": [
        "shared/*",
        "../shared/*",
        "../../packages/shared/*"
      ]
    },
    "typeRoots": [
      "./node_modules/@types",
      "./types"
    ]
  }
}

// Usage with path mapping
// Before: Relative imports
import { Button } from '../../../components/Button';
import { formatDate } from '../../../utils/date';
import config from '../../../config';

// After: Path mapping
import { Button } from '@components/Button';
import { formatDate } from '@utils/date';
import config from '@config';

// Using rootDirs for virtual directory structure
{
  "compilerOptions": {
    "rootDirs": [
      "src",
      "generated"
    ]
  }
}

// File structure:
// src/index.ts
// generated/api-types.ts

// In src/index.ts, can import as if in same directory
import { ApiTypes } from './api-types'; // Resolves to generated/api-types.ts

// Monorepo path mapping
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@myorg/core": ["packages/core/src"],
      "@myorg/utils": ["packages/utils/src"],
      "@myorg/ui": ["packages/ui/src"]
    }
  }
}

// JSON module resolution
{
  "compilerOptions": {
    "resolveJsonModule": true,
    "esModuleInterop": true
  }
}

import packageJson from './package.json';
console.log(packageJson.version); // Fully typed

4. Include/Exclude Patterns and File Selection

Pattern Description Example
* Matches zero or more characters (excluding directory separator) "src/*.ts" - all .ts files in src
? Matches exactly one character (excluding directory separator) "file?.ts" - file1.ts, fileA.ts
** Matches any directory nested to any level (recursive) "src/**/*.ts" - all .ts files recursively
include Files/patterns to include in compilation ["src/**/*", "types/**/*"]
exclude Files/patterns to exclude from compilation ["node_modules", "**/*.test.ts"]
files Explicit file list (takes precedence over include/exclude) ["src/main.ts", "src/types.d.ts"]
Default exclude Auto-excluded: node_modules, bower_components, jspm_packages, outDir Implicitly excluded unless in include
include priority include overrides default excludes (except outDir) ["node_modules/my-types/**/*"]

Example: File Selection Patterns

// Basic include/exclude patterns
{
  "include": [
    "src/**/*"  // All files in src directory recursively
  ],
  "exclude": [
    "node_modules",  // All node_modules
    "dist",           // Output directory
    "**/*.spec.ts",  // All test files
    "**/*.test.ts"   // All test files
  ]
}

// Multiple source directories
{
  "include": [
    "src/**/*",
    "lib/**/*",
    "types/**/*.d.ts"
  ],
  "exclude": [
    "src/**/*.test.ts",
    "lib/legacy/**/*"
  ]
}

// Explicit files list (overrides include/exclude)
{
  "files": [
    "src/main.ts",
    "src/types.d.ts",
    "src/global.d.ts"
  ]
  // No include/exclude needed when using files
}

// Complex pattern combinations
{
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "!src/**/*.test.ts",  // Negation pattern
    "!src/**/*.spec.ts"
  ],
  "exclude": [
    "**/*.d.ts",           // Exclude all declaration files
    "node_modules",
    "build",
    "dist",
    "coverage",
    ".vscode",
    ".git"
  ]
}

// Including specific files from node_modules
{
  "include": [
    "src/**/*",
    "node_modules/my-custom-types/**/*"  // Override default exclude
  ],
  "exclude": [
    "node_modules/my-custom-types/test/**/*"
  ]
}

// Monorepo file selection
{
  "include": [
    "packages/*/src/**/*.ts",
    "packages/*/src/**/*.tsx"
  ],
  "exclude": [
    "packages/*/node_modules",
    "packages/*/dist",
    "packages/*/**/*.test.ts"
  ]
}

// Test-specific configuration
// tsconfig.test.json
{
  "extends": "./tsconfig.json",
  "include": [
    "src/**/*.test.ts",
    "src/**/*.spec.ts",
    "test/**/*"
  ],
  "exclude": []  // Override parent exclude
}

// Build vs Dev configurations
// tsconfig.build.json
{
  "extends": "./tsconfig.json",
  "exclude": [
    "**/*.test.ts",
    "**/*.spec.ts",
    "**/__tests__/**",
    "**/__mocks__/**"
  ]
}

5. Project References and Composite Projects

Option Description Example
composite Enable project to be referenced and enable faster builds true (required for project references)
references Array of project references this project depends on [{ "path": "../core" }, { "path": "../utils" }]
declarationMap Generate source maps for .d.ts files (for Go to Definition) true (recommended with composite)
declaration Generate .d.ts files (automatically enabled with composite) true (auto-enabled)
incremental Enable incremental compilation (automatically enabled with composite) true (auto-enabled)
tsBuildInfoFile Specify file to store incremental compilation information "./dist/.tsbuildinfo"
--build flag Build mode for project references (tsc --build or tsc -b) tsc -b
prepend Prepend output of referenced project (for outFile) { "path": "../lib", "prepend": true }

Example: Project References Setup

// Monorepo structure
// /packages/core/tsconfig.json
{
  "compilerOptions": {
    "composite": true,
    "declaration": true,
    "declarationMap": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "tsBuildInfoFile": "./dist/.tsbuildinfo"
  },
  "include": ["src/**/*"]
}

// /packages/utils/tsconfig.json
{
  "compilerOptions": {
    "composite": true,
    "declaration": true,
    "declarationMap": true,
    "outDir": "./dist",
    "rootDir": "./src"
  },
  "references": [
    { "path": "../core" }  // Depends on core
  ],
  "include": ["src/**/*"]
}

// /packages/ui/tsconfig.json
{
  "compilerOptions": {
    "composite": true,
    "declaration": true,
    "declarationMap": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "jsx": "react-jsx"
  },
  "references": [
    { "path": "../core" },
    { "path": "../utils" }
  ],
  "include": ["src/**/*"]
}

// Root tsconfig.json (solution file)
{
  "files": [],
  "references": [
    { "path": "./packages/core" },
    { "path": "./packages/utils" },
    { "path": "./packages/ui" }
  ]
}

// Build commands
// Build all projects
tsc -b

// Build specific project and dependencies
tsc -b packages/ui

// Clean build artifacts
tsc -b --clean

// Force rebuild
tsc -b --force

// Watch mode for all projects
tsc -b --watch

// Verbose output
tsc -b --verbose

// Dry run
tsc -b --dry

// Using project references in code
// In packages/ui/src/Button.tsx
import { CoreService } from '@myorg/core';  // Reference from core
import { formatDate } from '@myorg/utils';  // Reference from utils

// Benefits of composite projects
// 1. Faster builds - only rebuild changed projects
// 2. Better IDE performance - jump to source instead of .d.ts
// 3. Enforce architectural boundaries
// 4. Parallel builds
// 5. Better error messages

// Build vs Solution configuration
// tsconfig.json (for IDE)
{
  "extends": "./tsconfig.base.json",
  "references": [
    { "path": "./packages/core" },
    { "path": "./packages/utils" }
  ]
}

// tsconfig.build.json (for production builds)
{
  "extends": "./tsconfig.base.json",
  "references": [
    { "path": "./packages/core" },
    { "path": "./packages/utils" }
  ],
  "compilerOptions": {
    "sourceMap": false,
    "declaration": true
  }
}

6. Build Mode and Incremental Compilation

Feature Description Configuration/Command
incremental Save information about project graph for faster rebuilds "incremental": true
tsBuildInfoFile Specify where to save incremental build info "tsBuildInfoFile": "./.tsbuildinfo"
--build (tsc -b) Build mode for project references with dependencies tsc -b or tsc --build
--watch Watch mode for automatic recompilation on file changes tsc --watch or tsc -w
--clean Delete outputs of specified projects (with -b) tsc -b --clean
--force Force rebuild of all projects (with -b) tsc -b --force
--verbose Show detailed build process information tsc -b --verbose
--dry Show what would be built without actually building tsc -b --dry
assumeChangesOnlyAffectDirectDependencies Optimize rebuild by limiting impact analysis "assumeChangesOnlyAffectDirectDependencies": true
watchOptions Configure file watching behavior for watch mode { "watchFile": "useFsEvents" }

Example: Incremental Build Configuration

// Enable incremental compilation
{
  "compilerOptions": {
    "incremental": true,
    "tsBuildInfoFile": "./dist/.tsbuildinfo",
    "outDir": "./dist"
  }
}

// Watch mode configuration
{
  "compilerOptions": {
    "incremental": true
  },
  "watchOptions": {
    // File watching strategies
    "watchFile": "useFsEvents",  // or "fixedPollingInterval", "dynamicPriorityPolling"
    "watchDirectory": "useFsEvents",  // or "fixedPollingInterval", "dynamicPriorityPolling"
    
    // Fallback polling for file systems that don't support events
    "fallbackPolling": "dynamicPriority",
    
    // Debounce settings
    "synchronousWatchDirectory": true,
    
    // Exclude directories from watching
    "excludeDirectories": [
      "**/node_modules",
      "**/.git",
      "**/dist"
    ],
    
    // Exclude files from watching
    "excludeFiles": [
      "**/.tsbuildinfo",
      "**/package-lock.json"
    ]
  }
}

// Build mode commands for project references
// Build all referenced projects
tsc -b

// Build with dependency tracking
tsc -b packages/app packages/lib

// Watch mode for project references
tsc -b --watch

// Clean build outputs
tsc -b --clean

// Force rebuild all
tsc -b --force

// Verbose build output
tsc -b --verbose

// Dry run (show what would be built)
tsc -b --dry

// Combined flags
tsc -b --clean --verbose
tsc -b --force --watch

// Optimize for large codebases
{
  "compilerOptions": {
    "incremental": true,
    "tsBuildInfoFile": "./.tsbuildinfo",
    
    // Speed optimizations
    "skipLibCheck": true,  // Skip type checking of .d.ts files
    "skipDefaultLibCheck": true,
    
    // For project references
    "assumeChangesOnlyAffectDirectDependencies": true
  }
}

// Parallel builds with project references
// package.json scripts
{
  "scripts": {
    "build": "tsc -b",
    "build:clean": "tsc -b --clean",
    "build:force": "tsc -b --force",
    "build:watch": "tsc -b --watch",
    "build:verbose": "tsc -b --verbose"
  }
}

// CI/CD optimized build
{
  "compilerOptions": {
    "incremental": false,  // Disable for clean CI builds
    "noEmitOnError": true,
    "skipLibCheck": true
  }
}

// Development vs Production configurations
// tsconfig.dev.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "incremental": true,
    "sourceMap": true,
    "declaration": false
  },
  "watchOptions": {
    "watchFile": "useFsEvents",
    "excludeDirectories": ["node_modules", "dist"]
  }
}

// tsconfig.prod.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "incremental": false,
    "sourceMap": false,
    "declaration": true,
    "removeComments": true
  }
}

// Build performance monitoring
// Use --diagnostics flag
tsc --diagnostics

// Output includes:
// Files:            350
// Lines:            45000
// Nodes:            250000
// Identifiers:      80000
// Symbols:          90000
// Types:            30000
// Memory used:      250MB
// I/O Read time:    0.5s
// Parse time:       2.3s
// Bind time:        1.1s
// Check time:       5.8s
// Emit time:        1.2s
// Total time:       10.9s
Note: Configuration best practices:
  • Use strict: true for all new projects to catch errors early
  • Enable incremental for faster development rebuilds
  • Use project references for monorepos and large codebases
  • Configure path mapping to avoid deep relative imports
  • Use extends to share common configurations
  • Separate dev/prod/test configurations with different tsconfig files
  • Add skipLibCheck to speed up compilation in large projects
  • Use tsc -b for project references with automatic dependency tracking
Warning: Configuration pitfalls:
  • Path mappings in tsconfig don't affect runtime - need bundler/Node.js module resolution
  • composite: true requires declaration: true and specific rootDir/outDir
  • include patterns override default excludes (except outDir)
  • types array limits type package inclusion - may break global types
  • watchOptions can significantly impact CPU usage - tune for your file system
  • strictPropertyInitialization requires constructor initialization or definite assignment
  • noUncheckedIndexedAccess adds undefined to all indexed access - affects existing code
  • Project references must use composite projects - can't mix with regular projects

Configuration and Compiler Options Summary

  • tsconfig.json - Main configuration file with compilerOptions, include, exclude, extends, references
  • Strict mode - Enable with strict: true plus additional checks like noUnusedLocals, noImplicitReturns
  • Path mapping - Use baseUrl and paths for clean imports, typeRoots for custom type locations
  • File selection - Glob patterns with *, ?, ** for include/exclude, files for explicit lists
  • Project references - composite: true enables faster monorepo builds with dependency tracking
  • Incremental builds - Enable incremental: true and use tsc -b for project references with caching