I Smell Good!

2026-05-26

I smell good and I will tell you about it!

Written by: MackSix

Goofy in the kitchen.

smell

goofy

kitchen

Chapter 14: Configuring TypeScript – tsconfig.json

Your tsconfig.json controls how strict TS is and how it compiles. Here are the options that actually matter.

Use this for most apps:

{
  "compilerOptions": {
    "skipLibCheck": true,
    "target": "es2022",
    "esModuleInterop": true,
    "allowJs": true,
    "resolveJsonModule": true,
    "moduleDetection": "force",
    "isolatedModules": true,
    "strict": true,
    "noUncheckedIndexedAccess": true,
    
    "module": "esnext",
    "moduleResolution": "bundler",
    "outDir": "dist",
    "rootDir": "src"
  },
  "include": ["src"]
}

2. The Important Flags Explained

FlagWhat it doesWhy you want it
strict: trueTurns on all strict checksCatches the most bugs. Always use.
noUncheckedIndexedAccess: truearr[0] might be undefinedForces you to handle missing array/object props
skipLibCheck: trueDon’t type-check .d.ts filesFaster compiles
target: "es2022"What JS version to outputUse modern features, let your bundler handle old browsers
module: "esnext"Use modern import/exportFor Vite, Webpack, etc
moduleResolution: "bundler"How imports resolveMatches modern bundlers
isolatedModules: trueEach file must be safely compilable aloneRequired for Babel, SWC, esbuild
moduleDetection: "force"Treat all .ts files as modulesAvoids global scope bugs from Ch.13
esModuleInterop: trueBetter CommonJS importsLets you import React from "react"
allowJs: trueImport .js filesFor gradual TS migration
resolveJsonModule: trueimport data from "./data.json"Useful for configs

3. strict Mode = Bundle of Checks

strict: true turns on these all at once:

"noImplicitAny": true,              // Error if TS can’t infer type
"strictNullChecks": true,           // null/undefined only assignable to themselves
"strictFunctionTypes": true,        // Stricter function param checking
"strictBindCallApply": true,        // Types bind/call/apply properly
"strictPropertyInitialization": true, // Class props must be initialized
"noImplicitThis": true,             // Error on `this` with type `any`
"alwaysStrict": true                // Emit "use strict"

4. Common Project Structure

{
  "compilerOptions": {
    "outDir": "./dist",    // Compiled JS goes here
    "rootDir": "./src",    // Your TS source
    "baseUrl": ".",        // For path aliases
    "paths": {
      "@/*": ["src/*"]     // import { x } from "@/utils"
    }
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
}

Bottom line:

  1. Start with strict: true + noUncheckedIndexedAccess: true – catches real bugs
  2. moduleResolution: "bundler" + isolatedModules: true for modern tooling
  3. moduleDetection: "force" prevents accidental globals
  4. Most other options you can ignore unless you have a specific need

Copy the base config above and you’re good for 95% of projects.