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