| |

TypeScript 72 🔷 Compiler Options in Depth

The tsconfig.json is not a configuration file. It is a program. Every flag in the compilerOptions object changes what the compiler accepts, what it rejects, what it emits, and how it resolves the modules. The previous chapter covered the strict flags, which are the safety’s core. This chapter covers the rest: the module system, the emit, the resolution, the interop, the performance, the decorators, and the advanced. The goal is not to memorize every option. It is to know which options exist, what each one does, and when the default is right and when it is wrong.

Key point: The compilerOptions object has the categories: the module’s (module, moduleResolution, esModuleInterop, verbatimModuleSyntax), the emit’s (target, outDir, declaration, sourceMap, removeComments), the resolution’s (baseUrl, paths, rootDirs, typeRoots), the checking’s (the strict family and the additional flags), the performance’s (incremental, tsBuildInfoFile, skipLibCheck), and the interop’s (allowSyntheticDefaultImports, resolveJsonModule, isolatedModules). The module’s options are the most consequential, and the module and the moduleResolution must agree. The target determines the emitted JavaScript’s version, and the lib determines the available APIs. The outDir and the rootDir determine the output’s structure. The declaration and the sourceMap determine the artifacts. The skipLibCheck is the performance’s, and the incremental is the build’s.


The module and the moduleResolution

The two options determine the module system and the resolution’s algorithm. The two must agree, and the wrong pair produces the resolution’s errors .

The module. The module specifies what module code is generated. The values are none, commonjs, amd, umd, system, es2015, es2020, es2022, esnext, node16, node18, node20, nodenext, preserve .

Why the module matters. The module determines the emitted JavaScript’s module syntax. The commonjs emits require, the esnext emits import, and the nodenext emits the format that matches the file’s extension and the package.json‘s type .

The moduleResolution. The moduleResolution specifies how TypeScript looks up a file from a module specifier. The values are classic, node10, node16, nodenext, bundler .

The node10 (the legacy). The node10 (previously the node) is the Node.js versions older than v10, which only support the CommonJS’s require. The node10 does not require the file’s extension, and it does not read the package.json‘s exports .

The node16 and the nodenext. The node16 and the nodenext are the modern Node.js, which support the ECMAScript’s import and the CommonJS’s require. The two read the package.json‘s exports and require the file’s extension on the relative paths .

The bundler. The bundler is the bundlers’ (Vite, Webpack, esbuild). The bundler supports the package.json‘s imports and exports, but it does not require the file’s extension on the relative paths .

Why the pair matters. The module and the moduleResolution must agree. The module: nodenext and the moduleResolution: nodenext are the pair, and the module: esnext and the moduleResolution: bundler are the pair. The mismatched pair produces the resolution’s errors and the emit’s errors .


The target and the lib

The target determines the emitted JavaScript’s version, and the lib determines the available APIs.

The target. The target sets the JavaScript’s language version for the emitted output and includes the compatible library declarations. The values are es3, es5, es2015, es2016, es2017, es2018, es2019, es2020, es2021, es2022, esnext .

Why the target matters. The target determines the syntax that the emitted JavaScript uses. The es5 emits the var and the function expressions, and the es2022 emits the const, the arrow functions, and the optional chaining. The lower the target, the more the downleveling .

The lib. The lib is the list of the bundled library declaration files that describe the target runtime environment. The values include es5, es2015, es2020, dom, dom.iterable, webworker, scripthost .

Why the lib matters. The lib determines the APIs that TypeScript knows about. The dom provides the document and the window, and the es2020 provides the Promise.allSettled and the BigInt. The Node.js project excludes the dom and includes the @types/node .

The default’s behavior. The target includes the compatible lib by default. The target: es2020 includes the es2020 and the lower. The explicit lib overrides the default, and the explicit is the control .

Why the explicit’s lib matters. The explicit’s lib is the precision’s, and the precision’s is the Node.js’s. The Node.js’s lib: ["es2023"] excludes the dom, and the dom‘s is the browser’s. The two are the different, and the different is the project’s .


The outDir, the rootDir, and the declaration

The three options determine the output’s structure and the artifacts.

The outDir. The outDir specifies an output folder for all emitted files. The default is the source’s directory, which overwrites the source’s .

Why the outDir matters. The outDir separates the output from the source, and the separation is the safety’s. The outDir: "./dist" is the convention’s, and the convention’s is the build’s .

The rootDir. The rootDir specifies the root folder within the source files. The outDir‘s structure mirrors the rootDir‘s, and the mirror is the organization’s .

Why the rootDir matters. The rootDir determines the output’s structure. The rootDir: "./src" and the outDir: "./dist" produce the dist/ that mirrors the src/. The wrong rootDir produces the nested’s, and the nested’s is the confusion’s .

The declaration. The declaration generates the .d.ts files from the TypeScript and the JavaScript files. The .d.ts is the types’s, and the types’s is the library’s .

Why the declaration matters. The declaration: true is the library’s, and the library’s is the consumer’s. The .d.ts is the contract’s, and the contract’s is the API’s. The declarationMap: true adds the map’s, and the map’s is the source’s .

The declarationMap and the sourceMap. The declarationMap generates the map for the .d.ts, and the sourceMap generates the map for the .js. The two are the debugging’s, and the debugging’s is the development’s .

Why the maps matter. The maps connect the output to the source, and the connection is the debugger’s. The sourceMap: true is the JavaScript’s, and the declarationMap: true is the types’s. The two are the development’s, and the development’s is the productivity’s .


The esModuleInterop and the allowSyntheticDefaultImports

The two options control the CommonJS and the ESM’s interop.

The esModuleInterop. The esModuleInterop emits the additional JavaScript to ease the support for importing the CommonJS modules. It enables the allowSyntheticDefaultImports for the type compatibility .

Why the esModuleInterop matters. The esModuleInterop fixes the CommonJS and the ESM’s interop. Without it, the import * as React from 'react' is the pattern’s. With it, the import React from 'react' is the pattern’s, and the pattern’s is the modern .

The allowSyntheticDefaultImports. The allowSyntheticDefaultImports allows the default imports from the modules that do not have the default export. The esModuleInterop implies the allowSyntheticDefaultImports, but the explicit is clearer .

Why the allowSyntheticDefaultImports matters. The allowSyntheticDefaultImports is the type’s, and the type’s is the check’s. The esModuleInterop is the runtime’s, and the runtime’s is the emit’s. The two are the pair, and the pair is the interop’s .

The resolveJsonModule. The resolveJsonModule imports the JSON files as the modules. The import config from './config.json' is the pattern’s, and the pattern’s is the modern .

Why the resolveJsonModule matters. The resolveJsonModule is the JSON’s, and the JSON’s is the config’s. The resolveJsonModule: true is the convenience’s, and the convenience’s is the pattern’s .


The verbatimModuleSyntax and the isolatedModules

The two options control the module’s emit and the transpilation.

The verbatimModuleSyntax. The verbatimModuleSyntax requires the explicit type modifier for the type-only imports. The import type { User } from './types' is the pattern’s, and the pattern’s is the modern .

Why the verbatimModuleSyntax matters. The verbatimModuleSyntax protects against the module-related pitfalls. It prevents the ambiguous import statements, and the ambiguity is the bug’s. It prevents the export default in the modules that will be emitted as the CommonJS, and the CommonJS’s is the consumer’s .

The isolatedModules. The isolatedModules ensures that each file can be safely transpiled without relying on the other imports. It is critical for Vite, esbuild, and the other transpilers that transpile the file-by-file .

Why the isolatedModules matters. The isolatedModules catches the files without the imports or the exports, the type-only imports not marked as such, and the const enum‘s. The transpiler’s is the file-by-file’s, and the file-by-file’s is the modern’s .

The moduleDetection. The moduleDetection specifies what method is used to detect whether a file is a script or a module. The auto, the legacy, the force are the values .

Why the moduleDetection matters. The moduleDetection: "force" treats all files as modules, and the modules are the no-accidental-globals. The force is the modern’s, and the modern’s is the safe’s .


The skipLibCheck and the incremental

The two options are the performance’s.

The skipLibCheck. The skipLibCheck skips the type checking of the declaration files. The skipLibCheck: true is the performance’s, and the performance’s is the 29% improvement’s .

Why the skipLibCheck matters. The skipLibCheck is the declaration files’s, and the declaration files’s are the library’s. The consumer’s code is still checked against the types, and the check’s is the safety’s. The skipLibCheck: true is the recommendation’s .

The incremental. The incremental saves the .tsbuildinfo files to allow for the incremental compilation of the projects. The subsequent compilations only recheck the changed files and their dependents .

Why the incremental matters. The incremental is the 50-90% faster rebuilds’s, and the rebuilds’s is the development’s. The tsBuildInfoFile specifies the file’s location, and the location’s is the cache’s .

The composite. The composite is the monorepo’s, and the monorepo’s is the multi-project’s. The composite: true implies the incremental: true and requires the declaration: true .

Why the composite matters. The composite is the project’s references’s, and the references’s is the monorepo’s. The references array declares the dependencies, and the dependencies’s is the build’s .


The experimentalDecorators and the emitDecoratorMetadata

The two options control the decorators.

The experimentalDecorators. The experimentalDecorators enables the experimental support for the TC39 stage 2 draft decorators. The legacy’s decorators require the flag .

Why the experimentalDecorators matters. The experimentalDecorators is the legacy’s, and the legacy’s is the Angular’s and the TypeORM’s. The modern’s decorators (the TC39 stage 3) do not require the flag, and the modern’s is the new’s .

The emitDecoratorMetadata. The emitDecoratorMetadata emits the design-type metadata for the decorated declarations. The metadata’s is the reflection’s, and the reflection’s is the DI’s .

Why the emitDecoratorMetadata matters. The emitDecoratorMetadata is the reflect-metadata‘s, and the reflect-metadata‘s is the runtime’s. The Angular’s and the TypeORM’s use the metadata’s, and the metadata’s is the DI’s .

The modern’s decorators. The ES spec decorators do not support the emitDecoratorMetadata, and the reflect-metadata is the legacy’s. The modern’s is the standard’s, and the standard’s is the new’s .


The other options

The remaining options are the specific’s, and each has the use.

The forceConsistentCasingInFileNames. The forceConsistentCasingInFileNames ensures that the casing is correct in the imports. The cross-platform’s is the macOS’s and the Windows’s .

Why the forceConsistentCasingInFileNames matters. The Linux’s is the case-sensitive’s, and the macOS’s and the Windows’s are the case-insensitive’s. The import’s casing must match the file’s, and the match’s is the cross-platform’s .

The noUnusedLocals and the noUnusedParameters. The two report the unused locals and the unused parameters. The two are the lint’s, and the lint’s is the cleanup’s .

Why the two matter. The unused locals and the parameters are the dead code’s, and the dead code’s is the maintenance’s. The two are the cleanup’s, and the cleanup’s is the quality’s .

The removeComments. The removeComments removes the comments from the output. The removeComments: true is the bundle’s, and the bundle’s is the size’s .

Why the removeComments matters. The comments are the source’s, and the source’s is the development’s. The output’s is the production’s, and the production’s is the size’s. The two are the different, and the different is the build’s .

The importHelpers. The importHelpers imports the helper functions from the tslib once per project, instead of including them per-file. The importHelpers: true is the bundle’s, and the bundle’s is the size’s .

Why the importHelpers matters. The helpers are the downlevel’s, and the downlevel’s is the spread’s, the async’s, the generator’s. The per-file’s is the duplication’s, and the duplication’s is the size’s. The importHelpers is the tslib‘s, and the tslib‘s is the shared’s .

The downlevelIteration. The downlevelIteration emits the more compliant, but verbose and less performant, JavaScript for the iteration. The for...of and the spread’s are the downlevel’s .

Why the downlevelIteration matters. The downlevelIteration is the ES5’s and the ES3’s, and the target’s is the older’s. The for...of‘s is the iteration’s, and the iteration’s is the array’s and the string’s. The downlevelIteration: true is the compliant’s, and the compliant’s is the correctness’s .

The baseUrl and the paths. The baseUrl is the base directory for the non-relative module names, and the paths is the mapping. The two are the alias’s, and the alias’s is the import’s .

Why the baseUrl and the paths matter. The two are the alias’s, and the alias’s is the @app/‘s. The paths’s is the convenience’s, and the convenience’s is the import’s. The two are the pair, and the pair is the resolution’s .

The typeRoots and the types. The typeRoots is the directories for the type packages, and the types is the specific packages. The two are the @types‘s, and the @types‘s is the global’s .

Why the two matter. The typeRoots and the types control the global’s type packages. The types: ["node", "jest"] limits the loaded packages, and the limit’s is the performance’s .


Complete Example Session

// tsconfig.json — the full reference
{
  "compilerOptions": {
    // ============================================
    // THE LANGUAGE AND THE ENVIRONMENT
    // ============================================
    "target": "es2022",
    "lib": ["es2022", "dom", "dom.iterable"],
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "moduleDetection": "force",

    // ============================================
    // THE INTEROP
    // ============================================
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "resolveJsonModule": true,
    "verbatimModuleSyntax": true,
    "isolatedModules": true,

    // ============================================
    // THE EMIT
    // ============================================
    "outDir": "./dist",
    "rootDir": "./src",
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "removeComments": false,
    "importHelpers": true,
    "downlevelIteration": true,

    // ============================================
    // THE STRICT
    // ============================================
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitOverride": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,

    // ============================================
    // THE LINT
    // ============================================
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "forceConsistentCasingInFileNames": true,

    // ============================================
    // THE PERFORMANCE
    // ============================================
    "skipLibCheck": true,
    "incremental": true,
    "tsBuildInfoFile": "./dist/.tsbuildinfo",

    // ============================================
    // THE DECORATORS (if needed)
    // ============================================
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,

    // ============================================
    // THE RESOLUTION
    // ============================================
    "baseUrl": "./src",
    "paths": {
      "@app/*": ["app/*"],
      "@utils/*": ["utils/*"]
    },
    "typeRoots": ["./node_modules/@types"],
    "types": ["node", "jest"]
  },
  "include": ["src", "types"],
  "exclude": ["node_modules", "dist"]
}

The configuration above is the reference’s, and it is not the recommendation’s for every project. The project’s is the specific’s, and the specific’s is the design’s. The target, the module, the moduleResolution, and the lib are the foundation’s, and the foundation’s is the runtime’s. The strict‘s family is the safety’s, and the safety’s is the core’s. The outDir‘s, the rootDir‘s, and the declaration‘s are the library’s, and the library’s is the consumer’s. The skipLibCheck‘s and the incremental‘s are the performance’s, and the performance’s is the development’s.


Quick Reference

The Module’s Options

OptionPurpose
moduleThe emitted module syntax
moduleResolutionThe resolution’s algorithm
moduleDetectionThe module vs script’s detection
esModuleInteropThe CJS/ESM’s interop
verbatimModuleSyntaxThe explicit type’s import
isolatedModulesThe file-by-file’s transpilation
resolveJsonModuleThe JSON’s import

The Emit’s Options

OptionPurpose
targetThe JavaScript’s version
libThe available APIs
outDirThe output’s directory
rootDirThe source’s root
declarationThe .d.ts files
declarationMapThe .d.ts.map files
sourceMapThe .js.map files
removeCommentsThe comments’s removal
importHelpersThe tslib‘s helpers

The Resolution’s Options

OptionPurpose
baseUrlThe non-relative’s base
pathsThe alias’s mapping
typeRootsThe @types‘s directories
typesThe specific @types‘s

The Performance’s Options

OptionPurpose
skipLibCheckThe declaration’s skip
incrementalThe incremental’s build
tsBuildInfoFileThe cache’s file
compositeThe monorepo’s project

The Decorators’ Options

OptionPurpose
experimentalDecoratorsThe legacy’s decorators
emitDecoratorMetadataThe design-type’s metadata

The Checking’s Options

OptionPurpose
strictThe strict’s umbrella
noUnusedLocalsThe unused locals
noUnusedParametersThe unused parameters
forceConsistentCasingInFileNamesThe casing’s check

Best Practices

✅ Do This:

// Match module and moduleResolution
{ "module": "nodenext", "moduleResolution": "nodenext" }        // ✅
// Use the esModuleInterop for the CJS/ESM
{ "esModuleInterop": true }                                     // ✅
// Use the verbatimModuleSyntax for the library
{ "verbatimModuleSyntax": true }                                // ✅
// Use the skipLibCheck for the performance
{ "skipLibCheck": true }                                        // ✅
// Use the incremental for the build
{ "incremental": true, "tsBuildInfoFile": "./dist/.tsbuildinfo" } // ✅
// Use the declaration for the library
{ "declaration": true, "declarationMap": true }                 // ✅
// Use the outDir and the rootDir
{ "outDir": "./dist", "rootDir": "./src" }                      // ✅

❌ Don’t Do This:

// Don't mismatch the module and moduleResolution
{ "module": "esnext", "moduleResolution": "nodenext" }          // ⚠️
// Don't use the node10 for the modern
{ "moduleResolution": "node10" }                                // ⚠️
// Don't forget the lib for the Node.js
{ "lib": ["dom"] }  // the Node.js has no DOM                    // ⚠️
// Don't use the outDir's default
{ "outDir": "./src" }  // overwrites the source                  // ⚠️
// Don't forget the declaration for the library
{ "declaration": false }  // the consumer's no types              // ⚠️
// Don't use the experimentalDecorators without the need
{ "experimentalDecorators": true }  // the modern's is the default // ⚠️

Common Pitfalls

PitfallProblemSolution
The mismatched module pairThe resolution’s errorsThe same pair
The node10 in the modernThe legacyThe nodenext
The dom in the Node.jsThe wrong APIsThe lib: ["es2023"]
The outDir‘s defaultThe source’s overwriteThe outDir: "./dist"
The missing declarationThe consumer’s no typesThe declaration: true
The missing skipLibCheckThe slow buildThe skipLibCheck: true
The missing incrementalThe slow rebuildThe incremental: true
The missing verbatimModuleSyntaxThe ambiguous importThe verbatimModuleSyntax: true

Real-World Examples

1. The Node.js library’s tsconfig

{
  "compilerOptions": {
    "target": "es2022",
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "strict": true,
    "verbatimModuleSyntax": true,
    "declaration": true,
    "sourceMap": true,
    "declarationMap": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "skipLibCheck": true
  }
}

2. The React app’s tsconfig

{
  "compilerOptions": {
    "target": "es2022",
    "lib": ["es2022", "dom", "dom.iterable"],
    "module": "esnext",
    "moduleResolution": "bundler",
    "jsx": "react-jsx",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "isolatedModules": true,
    "noEmit": true
  }
}

3. The esModuleInterop‘s effect

// Without:
import * as React from 'react';

// With:
import React from 'react';

4. The verbatimModuleSyntax‘s effect

// The wrong:
import { User } from './types';  // ambiguous

// The right:
import type { User } from './types';  // explicit

5. The isolatedModules‘s effect

// The wrong:
export { SomeType };  // the type-only

// The right:
export type { SomeType };  // explicit

6. The skipLibCheck‘s effect

{ "skipLibCheck": true }  // the 29% faster

7. The incremental‘s effect

{ "incremental": true, "tsBuildInfoFile": "./dist/.tsbuildinfo" }

8. The declaration‘s effect

{ "declaration": true, "declarationMap": true }

9. The paths‘s effect

{
  "baseUrl": "./src",
  "paths": { "@app/*": ["app/*"] }
}

10. The typeRoots‘s effect

{ "typeRoots": ["./node_modules/@types", "./typings"] }

Visual: The Module’s Pair

┌──────────────────────────────────────────────────────────┐
│  THE NODE.JS                                             │
│    The module: nodenext                                  │
│    The moduleResolution: nodenext                        │
│    The extension: required                               │
│    The exports: honored                                  │
│                                                          │
├──────────────────────────────────────────────────────────┤
│  THE BUNDLER                                             │
│    The module: esnext                                    │
│    The moduleResolution: bundler                         │
│    The extension: optional                               │
│    The exports: honored                                  │
│                                                          │
├──────────────────────────────────────────────────────────┤
│  THE LEGACY                                              │
│    The module: commonjs                                  │
│    The moduleResolution: node10                          │
│    The extension: optional                               │
│    The exports: ignored                                  │
│                                                          │
│  The module and the moduleResolution must agree.         │
│                                                          │
└──────────────────────────────────────────────────────────┘

Visual: The Emit’s Options

┌──────────────────────────────────────────────────────────┐
│  THE SOURCE                                              │
│    src/                                                  │
│      index.ts                                            │
│      utils.ts                                            │
│                                                          │
│         │  The compiler                                  │
│         ▼                                                │
│                                                          │
│  THE OUTPUT                                              │
│    dist/                                                 │
│      index.js      ← the JavaScript                      │
│      index.d.ts    ← the declarations                    │
│      index.js.map  ← the source map                      │
│      index.d.ts.map ← the declaration map                │
│      utils.js                                            │
│      utils.d.ts                                          │
│                                                          │
│  The outDir and the rootDir determine the structure.     │
│                                                          │
└──────────────────────────────────────────────────────────┘

Visual: The Performance’s Options

┌──────────────────────────────────────────────────────────┐
│  THE WITHOUT                                             │
│    The full rebuild: 15s                                 │
│    The skipLibCheck: off                                 │
│    The incremental: off                                  │
│                                                          │
├──────────────────────────────────────────────────────────┤
│  THE WITH                                                │
│    The first build: 15s                                  │
│    The subsequent: 1-3s                                  │
│    The skipLibCheck: on                                  │
│    The incremental: on                                   │
│                                                          │
│  The 50-90% faster rebuilds.                             │
│                                                          │
└──────────────────────────────────────────────────────────┘

Visual: The Interop’s Options

┌──────────────────────────────────────────────────────────┐
│  THE esModuleInterop                                     │
│    The import React from 'react'                         │
│    The CJS's default's                                   │
│                                                          │
├──────────────────────────────────────────────────────────┤
│  THE verbatimModuleSyntax                                │
│    The import type { User } from './types'               │
│    The explicit's                                        │
│                                                          │
├──────────────────────────────────────────────────────────┤
│  THE isolatedModules                                     │
│    The export type { User }                              │
│    The file-by-file's                                    │
│                                                          │
│  The three are the modern's interop's.                   │
│                                                          │
└──────────────────────────────────────────────────────────┘

Visual: The tsconfig’s Structure

┌──────────────────────────────────────────────────────────┐
│  THE tsconfig.json                                       │
│    │                                                     │
│    ├── The compilerOptions                               │
│    │     ├── The module's                                │
│    │     ├── The emit's                                  │
│    │     ├── The checking's                              │
│    │     ├── The resolution's                            │
│    │     ├── The performance's                           │
│    │     └── The interop's                               │
│    │                                                     │
│    ├── The include                                       │
│    ├── The exclude                                       │
│    ├── The files                                         │
│    └── The references                                    │
│                                                          │
│  The compilerOptions is the program's, and the include    │
│  and the exclude are the scope's.                        │
│                                                          │
└──────────────────────────────────────────────────────────┘

Summary

CategoryOptions
The module’smodule, moduleResolution, moduleDetection, esModuleInterop, verbatimModuleSyntax, isolatedModules, resolveJsonModule
The emit’starget, lib, outDir, rootDir, declaration, declarationMap, sourceMap, removeComments, importHelpers
The checking’sstrict, the additional flags, noUnusedLocals, noUnusedParameters
The resolution’sbaseUrl, paths, typeRoots, types
The performance’sskipLibCheck, incremental, tsBuildInfoFile, composite
The decorators’experimentalDecorators, emitDecoratorMetadata
The interop’sesModuleInterop, allowSyntheticDefaultImports, resolveJsonModule

Key takeaways:

  • The module and the moduleResolution must agree — the nodenext pair for the Node.js, the bundler pair for the bundler, and the mismatch produces the resolution’s errors
  • The target determines the emitted JavaScript’s version, and the lib determines the available APIs — the Node.js excludes the dom, and the browser includes it
  • The outDir and the rootDir determine the output’s structure — the outDir: "./dist" and the rootDir: "./src" produce the mirrored output
  • The declaration and the sourceMap determine the artifacts — the .d.ts for the consumer, the .js.map for the debugger
  • The esModuleInterop fixes the CJS/ESM’s interop — the import React from 'react' is the modern’s
  • The verbatimModuleSyntax requires the explicit type’s import — the import type is the pattern’s, and the bundler can tree-shake
  • The isolatedModules ensures the file-by-file’s transpilation — the Vite and the esbuild are the file-by-file’s
  • The skipLibCheck and the incremental are the performance’s — the skipLibCheck is the 29% faster, and the incremental is the 50-90% faster
  • The experimentalDecorators and the emitDecoratorMetadata are the legacy’s — the modern’s decorators are the standard’s
  • The paths and the typeRoots are the resolution’s — the paths is the alias’s, and the typeRoots is the @types‘s

Remember: The compilerOptions is the program’s configuration, and each option changes the compiler’s behavior. The module’s options determine the resolution and the emit, the emit’s options determine the output, the checking’s options determine the safety, and the performance’s options determine the speed. The defaults are the sensible’s for the simple’s, and the explicit’s is the control’s. The tsconfig is the source’s, and the source’s is the project’s.


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!