Strict TypeScript tsconfig for a React App

TypeScript's strict mode is the single highest-leverage configuration option for improving code quality: it enables a collection of type-checking rules that catch the most common categories of runtime errors — null pointer exceptions, accessing undefined array indices, passing the wrong argument types — at compile time instead of in production. This tsconfig shows the strictest possible configuration, going beyond the standard strict flag to include additional checks that TypeScript ships but doesn't enable by default. The target: "ES2022" tells TypeScript to compile to ES2022 JavaScript, preserving modern features like top-level await, class fields, and Array.at() that all modern runtime environments support. lib: ["ES2022", "DOM", "DOM.Iterable"] includes type definitions for ES2022 built-ins and browser DOM APIs. module: "ESNext" and moduleResolution: "bundler" configure module handling for Vite, esbuild, or other modern bundlers that use native ES modules. The strict: true flag is a meta-flag that enables: strictNullChecks (null and undefined are distinct types, not assignable to everything), noImplicitAny (variables must have explicit types, not implicit any), strictFunctionTypes (function parameter types are checked contravariantly), strictBindCallApply (bind/call/apply check argument types), strictPropertyInitialization (class properties must be initialized in the constructor), and several others. Beyond strict, this config adds: noUncheckedIndexedAccess changes the type of array[index] and object[key] from T to T | undefined, forcing you to handle the case where the index doesn't exist. This prevents a very common class of runtime errors where code assumes array[0] is always defined. exactOptionalPropertyTypes prevents assigning undefined to optional properties that weren't declared as | undefined — { foo?: string } doesn't accept { foo: undefined } by default. noImplicitReturns requires all code paths in a function to explicitly return a value if the return type isn't void or any. noFallthroughCasesInSwitch prevents unintentional switch case fallthrough. forceConsistentCasingInFileNames prevents case-sensitive import bugs on case-insensitive filesystems (macOS, Windows) where import './Component' and import './component' refer to the same file but would fail on Linux CI. skipLibCheck: true skips type checking of declaration files in node_modules, which speeds up compilation significantly and avoids errors in third-party types that you can't fix anyway. Retrofitting advice: if you're adding strict mode to an existing project, start by adding // @ts-nocheck to files with many errors and enabling strict mode globally. Then work through files one by one, removing the nocheck comment and fixing errors. This staged approach is more manageable than fixing all errors at once.

Example
{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["ES2022", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "moduleResolution": "bundler",
    "jsx": "react-jsx",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
}
[ open in JSON Formatter → ]

FAQ

What does noUncheckedIndexedAccess do?
It adds undefined to the type of array and object index access results. Without it, array[0] has type T even if the array is empty. With it, you must handle the undefined case, preventing many runtime crashes.
Should I enable skipLibCheck?
Yes for most projects. skipLibCheck skips type checking of declaration files in node_modules. Checking them is slow and often flags bugs in third-party types that you cannot fix.
What is the difference between strict and strictest TypeScript?
The strict flag enables strictNullChecks, noImplicitAny, strictFunctionTypes, and others. Strictest adds noUncheckedIndexedAccess and exactOptionalPropertyTypes on top, which strict does not include.

Related Examples