TypeScript Configuration
TypeScript configuration is managed through the tsconfig.json
file, which specifies compiler options, file inclusion/exclusion patterns, and project settings. Proper configuration is essential for optimal development experience, build performance, and type checking accuracy.
Understanding TypeScript configuration options enables you to tailor the compiler behavior to your project's specific needs, from strict type checking to module resolution and output formatting.
Basic tsconfig.json Structure
The tsconfig.json
file defines how TypeScript should compile your project.
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"lib": ["es2020", "dom"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"dist",
"**/*.test.ts"
]
}
File Inclusion and Exclusion
Control which files TypeScript processes using include, exclude, and files options.
{
"compilerOptions": { /* ... */ },
// Include patterns (glob patterns)
"include": [
"src/**/*", // All files in src directory
"types/**/*", // Custom type definitions
"scripts/*.ts" // TypeScript files in scripts
],
// Exclude patterns (overrides include)
"exclude": [
"node_modules", // Third-party packages
"dist", // Output directory
"**/*.test.ts", // Test files
"**/*.spec.ts", // Spec files
"coverage", // Test coverage
"*.config.js" // Config files
],
// Explicit file list (alternative to include)
"files": [
"src/index.ts",
"src/types.ts"
]
}
Essential Compiler Options
Type Checking Options
{
"compilerOptions": {
// Enable all strict type checking
"strict": true,
// Or enable individual strict options
"noImplicitAny": true, // Error on 'any' type
"noImplicitReturns": true, // Error on missing return
"noImplicitThis": true, // Error on 'this' with any type
"strictNullChecks": true, // Enable strict null checking
"strictFunctionTypes": true, // Strict function type checking
"strictBindCallApply": true, // Strict bind/call/apply
"strictPropertyInitialization": true, // Class property initialization
// Additional type checking
"noUnusedLocals": true, // Error on unused locals
"noUnusedParameters": true, // Error on unused parameters
"noFallthroughCasesInSwitch": true, // Error on switch fallthrough
"noUncheckedIndexedAccess": true, // Add undefined to index signatures
"exactOptionalPropertyTypes": true // Exact optional property types
}
}
Module and Output Options
{
"compilerOptions": {
// Module system
"module": "esnext", // ES modules
"target": "es2020", // Output JavaScript version
"lib": ["es2020", "dom"], // Available libraries
// Module resolution
"moduleResolution": "node", // Node.js module resolution
"allowSyntheticDefaultImports": true,
"esModuleInterop": true, // CommonJS/ES module interop
"resolveJsonModules": true, // Import JSON files
// Output options
"outDir": "./dist", // Output directory
"rootDir": "./src", // Root source directory
"declaration": true, // Generate .d.ts files
"declarationDir": "./types", // Declaration output directory
"sourceMap": true, // Generate source maps
"removeComments": true, // Remove comments from output
// File naming
"preserveConstEnums": true, // Keep const enums
"importsNotUsedAsValues": "error" // Error on unused imports
}
}
Path Mapping and Aliases
Configure path aliases for cleaner imports and better code organization.
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"], // @/utils/helper
"@components/*": ["src/components/*"], // @components/Button
"@utils/*": ["src/utils/*"], // @utils/helper
"@types/*": ["src/types/*"], // @types/User
"@assets/*": ["assets/*"], // @assets/logo.png
"@config": ["src/config/index"], // @config (single file)
"@api": ["src/api/index"] // @api (barrel export)
}
}
}
Usage with path mapping:
// Instead of relative imports
import { Button } from '../../../components/ui/Button';
import { validateEmail } from '../../utils/validation';
import { User } from '../types/User';
// Use clean aliases
import { Button } from '@components/ui/Button';
import { validateEmail } from '@utils/validation';
import { User } from '@types/User';
Environment-Specific Configurations
Development Configuration
// tsconfig.dev.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": true,
"incremental": true,
"tsBuildInfoFile": "./node_modules/.cache/typescript/dev-tsbuildinfo",
"noEmitOnError": false,
"preserveWatchOutput": true
},
"watchOptions": {
"watchFile": "useFsEvents",
"watchDirectory": "useFsEvents",
"fallbackPolling": "dynamicPriority",
"synchronousWatchDirectory": true,
"excludeDirectories": ["**/node_modules", "_build"]
}
}
Production Configuration
// tsconfig.prod.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"removeComments": true,
"noEmitOnError": true,
"declaration": true,
"declarationMap": true,
"stripInternal": true
},
"exclude": [
"**/*.test.ts",
"**/*.spec.ts",
"src/test-utils",
"src/__mocks__"
]
}
Testing Configuration
// tsconfig.test.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": ["jest", "node"],
"allowJs": true,
"noEmit": true
},
"include": [
"src/**/*",
"**/*.test.ts",
"**/*.spec.ts"
]
}
Project References
For monorepos and large projects, use project references to improve build performance.
// Root tsconfig.json
{
"files": [],
"references": [
{ "path": "./packages/shared" },
{ "path": "./packages/client" },
{ "path": "./packages/server" }
]
}
// packages/shared/tsconfig.json
{
"compilerOptions": {
"composite": true,
"declaration": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"]
}
// packages/client/tsconfig.json
{
"compilerOptions": {
"composite": true,
"outDir": "./dist",
"rootDir": "./src"
},
"references": [
{ "path": "../shared" }
],
"include": ["src/**/*"]
}
Advanced Configuration Options
Decorator Support
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "es2020"
}
}
JSX Configuration
{
"compilerOptions": {
"jsx": "react-jsx", // React 17+ JSX transform
"jsxImportSource": "react", // JSX import source
"allowJs": true, // Allow JavaScript files
"checkJs": true // Type check JavaScript files
}
}
Plugin Configuration
{
"compilerOptions": {
"plugins": [
{
"name": "typescript-plugin-css-modules",
"options": {
"classnameTransform": "camelCase"
}
},
{
"name": "@typescript-eslint/typescript-estree",
"strictMode": true
}
]
}
}
Configuration for Different Frameworks
Next.js Configuration
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "es6"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModules": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
Node.js Configuration
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"lib": ["es2020"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"types": ["node"],
"moduleResolution": "node"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Library Configuration
{
"compilerOptions": {
"target": "es2015",
"module": "esnext",
"lib": ["es2015", "dom"],
"declaration": true,
"declarationDir": "./types",
"outDir": "./dist",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
Build Performance Optimization
Incremental Compilation
{
"compilerOptions": {
"incremental": true,
"tsBuildInfoFile": "./node_modules/.cache/typescript/tsbuildinfo",
"assumeChangesOnlyAffectDirectDependencies": true
}
}
Skip Type Checking for Dependencies
{
"compilerOptions": {
"skipLibCheck": true, // Skip type checking of declaration files
"skipDefaultLibCheck": true // Skip default library checking
}
}
Watch Mode Options
{
"watchOptions": {
"watchFile": "useFsEvents",
"watchDirectory": "useFsEvents",
"fallbackPolling": "dynamicPriority",
"synchronousWatchDirectory": true,
"excludeDirectories": ["**/node_modules", "_build", "temp"]
}
}
Common Configuration Patterns
Strict Configuration
{
"compilerOptions": {
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"noImplicitOverride": true
}
}
Flexible Configuration
{
"compilerOptions": {
"strict": false,
"noImplicitAny": false,
"allowJs": true,
"checkJs": false,
"suppressImplicitAnyIndexErrors": true
}
}
Troubleshooting Common Issues
Module Resolution Issues
{
"compilerOptions": {
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModules": true,
"typeRoots": ["./node_modules/@types", "./src/types"]
}
}
Path Mapping Not Working
Ensure your bundler/runtime supports path mapping:
// For Jest
{
"jest": {
"moduleNameMapping": {
"^@/(.*)$": "<rootDir>/src/$1",
"^@components/(.*)$": "<rootDir>/src/components/$1"
}
}
}
Performance Issues
{
"compilerOptions": {
"skipLibCheck": true,
"incremental": true,
"isolatedModules": true
},
"exclude": [
"node_modules",
"**/*.test.ts",
"coverage"
]
}
TypeScript configuration is powerful and flexible, allowing you to customize the compiler behavior for your specific project needs. Start with a basic configuration and gradually add options as your project grows in complexity.