Skip to main content

typescript-config-json

At a basic level, every configuration is built around three main parts:

  • compilerOptions: These are the specific rules for how your code is checked and transformed.
  • include: This tells TypeScript which files to look at, usually everything in your src folder.
  • exclude: This tells it what to ignore, such as your node_modules. In a basic setup, you generally choose between two paths based on your environment:
  • For Bundlers (Vite, Webpack, etc.): Use "moduleResolution": "bundler". This is the modern standard for frontend projects. It is more permissive and matches how tools like Vite work, meaning you don't have to include file extensions (like .js) in your imports.
  • For Node.js:     ◦ CommonJS (Traditional): Use "moduleResolution": "node".    ◦ Modern ESM: Use "moduleResolution": "node16" or "nodenext". A key "quirk" here is that TypeScript will often require you to add explicit .js extensions to your imports, even if the file on your disk ends in .ts.If you ever run into "module not found" errors, you can set "traceResolution": true in your config to see exactly where TypeScript is looking for your files. Recommended Starting Configuration For most modern TypeScript projects, the following configuration serves as a robust "bare minimum" starting point:
{
"compilerOptions": {
/* Language and Environment */
"target": "ES2020",
"lib": ["ES2020"],

/* Modules */
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"resolveJsonModule": true,

/* Type Checking */
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,

/* Output */
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"sourceMap": true,

/* Build Performance */
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"incremental": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}

Essential Options Explained To understand why these specific options are included in a minimal setup, consider these key categories: - Type Safety (**strict**): Enabling "strict": true is highly recommended as a best practice because it activates a suite of individual checks (like noImplicitAny and strictNullChecks) that catch more errors at compile time. - Module Resolution:     ◦ For Node.js (CommonJS): Use "module": "commonjs" and "moduleResolution": "node".    ◦ For Bundlers (Vite, Webpack): Use "module": "esnext" and "moduleResolution": "bundler". This pairing is more permissive with file extensions and matches how modern bundlers resolve imports.- Output Settings:     ◦ target: Defines which JavaScript version the compiler emits. ES2020 is often chosen for its balance of modern features and native support for optional chaining and nullish coalescing.    ◦ outDir and rootDir: Clearly separate your source TypeScript files from the compiled JavaScript artifacts.- Build Optimization:     ◦ skipLibCheck: Speeds up compilation by skipping type checking of .d.ts files in node_modules, which avoids potential conflicts between library definitions.    ◦ incremental: Speeds up subsequent builds by only re-compiling files that have changed.Context-Specific Variants While the configuration above is general, the sources highlight that the "bare minimum" changes based on your environment: - React Applications: Often require additional settings like "jsx": "react-jsx" and specific library definitions such as "lib": ["DOM", "DOM.Iterable"]. - Monorepos: Frequently use a tsconfig.base.json file to house shared settings, which individual packages then extend using the "extends" property to maintain consistency.