← All Articles ⚙️ Configuration & DevOps Medium By Nishant Kumar Verma Updated

TypeScript Strict Mode Disabled: Why AI Code Turns Off Type Safety

13% of TypeScript projects we scanned never turned strict mode on. What strict mode catches, what changed in TypeScript 6.0, and how to switch it on.

CFG-007

Quick Answer

With strict off in tsconfig.json, TypeScript stops checking for null and undefined, lets parameters silently become any, and skips several other checks. In VibeDoctor's scans, 10 of 78 TypeScript projects (13%) had a tsconfig.json that never turned strict on. Before TypeScript 6.0 that means strict mode is off. The fix is one line, "strict": true, followed by npx tsc --noEmit and working through the errors it reports.

How Often We See It

These numbers come from VibeDoctor's scans of the 336 projects connected to an account, as of each project's most recent scan (May to October 2026). The TypeScript count uses the 127 projects with a file-by-file language breakdown. No project or owner is identified.

At the latest scan Projects
TypeScript projects 78
Neither strict nor noImplicitAny turned on 10 (13%)

TypeScript 6.0, released in March 2026, made strict default to true. On 6.0 and later, only an explicit "strict": false turns it off. On 5.x and earlier, leaving the line out means strict mode is off. Writing "strict": true explicitly is correct on every version.

We count a project as strict when any config in its chain turns strict or noImplicitAny on. That includes configs it extends or lists under references, which is how Vite templates and monorepos split their settings. A project that extends a preset we cannot read, such as an npm package, is not counted as off.

What TypeScript Strict Mode Actually Is

strict is a shorthand that turns on a family of compiler checks at once. Without it, TypeScript accepts many patterns that are normal in JavaScript but are common sources of runtime crashes.

The strict family:

  • strictNullChecks - requires explicit handling of null and undefined
  • noImplicitAny - stops variables and parameters from silently becoming any
  • strictFunctionTypes - checks function parameter types properly when callbacks are passed around
  • strictBindCallApply - type-checks bind, call and apply
  • strictPropertyInitialization - ensures class properties are initialized in the constructor
  • noImplicitThis - flags this with an implicit any type
  • alwaysStrict - emits "use strict" in every output file
  • useUnknownInCatchVariables - types caught errors as unknown instead of any
  • strictBuiltinIteratorReturn - stricter types for built-in iterators (TypeScript 5.6 and later)

Of these, strictNullChecks usually catches the most real bugs: it is the one behind "Cannot read properties of undefined".

One limit to know about: strictFunctionTypes does not apply to methods. The TypeScript docs explain that it covers functions written in function syntax only, because the team found many unsafe class hierarchies, including some in the DOM, while building it. So a type written as func(x: string | number): void still accepts a function that takes only a string, while func: (x: string | number) => void is rejected under strict mode.

Why AI-Generated Projects End Up With Strict Off

Strict mode makes the compiler complain about code that runs fine in the happy path: reading a property of something that might be undefined, or passing a loosely typed callback. When an AI assistant or a hurried developer hits a wall of type errors, turning strict off is the fastest way to a green build. The code still looks typed, but most of the safety is gone.

// BAD - tsconfig.json with strict disabled
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "strict": false,
    "skipLibCheck": true,
    "moduleResolution": "bundler"
  }
}

With this config, the following compiles with zero errors, bugs included:

// All of these compile with strict: false
function getUsername(user) {          // implicit any - no error
  return user.profile.name.trim();    // no null check - no error
}

const id = getUserId();               // could be undefined - no error
const record = records[id];           // undefined key - no error
console.log(record.createdAt);        // crashes at runtime

What You Get With Strict Mode On

// GOOD - tsconfig.json: "strict": true

function getUsername(user: User): string {
  if (!user.profile) return 'Anonymous';   // required by strictNullChecks
  return user.profile.name?.trim() ?? '';
}

const id = getUserId();
if (id === undefined) throw new Error('No ID');
const record = records[id];
console.log(record?.createdAt ?? 'unknown');

With strict: true, TypeScript makes you deal with every possible null dereference, implicit any and unsafe callback at compile time, before a user hits the crash.

Strict Mode Impact by Flag

Flag What It Catches Bug Class Prevented
strictNullChecks Property access on values that may be null or undefined Cannot read properties of undefined
noImplicitAny Variables and parameters without a type Untyped code bypassing every other check
strictPropertyInitialization Class properties not assigned in the constructor Fields used before they are set
useUnknownInCatchVariables Reading .message on a caught error without narrowing Crash when something other than an Error is thrown
strictFunctionTypes Incompatible callback signatures Wrong argument type passed to callbacks

How to Turn Strict Mode On in an Existing Project

On a large AI-generated codebase, switching strict on can produce dozens of errors at once. Work through them in stages:

  1. Turn strict on and list the errors: set "strict": true and run npx tsc --noEmit, which type-checks without writing output files.
  2. Fix noImplicitAny errors first: usually the easiest, by adding types to parameters and variables.
  3. Work through strictNullChecks: for each error, decide whether the value can really be null. If yes, add a guard. If no, use the ! assertion, but only where you are certain.
  4. Mark what you cannot fix yet: put // @ts-expect-error with a short reason on the line instead of turning strict off again. You get a searchable list of what is left.
  5. Keep it on: VibeDoctor's Vibe Check reads your tsconfig.json, follows extends and references, and reports check CFG-007 when none of those configs turns strict on. Free to sign up.

In Next.js, also check next.config.js for typescript: { ignoreBuildErrors: true }. That setting lets next build succeed with type errors, so strict mode never blocks a broken deploy.

FAQ

Can I enable individual strict flags instead of the full strict bundle?

Yes. Every flag in the family can be turned on by itself. If strict: true produces too many errors at once, start with "strictNullChecks": true alone, then add the others one at a time as you clear the errors each one brings.

What is TS7053, and why does it disappear when strict is false?

TS7053 reads "Element implicitly has an 'any' type because expression of type 'string' can't be used to index type ...". It is a noImplicitAny error, so it appears whenever noImplicitAny is on, directly or through strict, and goes away only when both are off. Turning them off hides the problem rather than fixing it. Fix the index instead: type the key as keyof typeof colors, give the object an index signature such as Record<string, string>, or check name in colors before reading.

Why does strictFunctionTypes not check my methods?

By design. strictFunctionTypes applies only to functions written in function syntax, such as onChange: (value: string) => void, not to methods written as onChange(value: string): void. Write the type as a function property when you want parameters checked strictly.

Does strict mode slow down TypeScript compilation?

Barely. The extra analysis adds a little compile time, which is negligible next to the cost of a null reference error in production.

What is skipLibCheck and should I set it to false?

skipLibCheck: true skips type-checking the declaration files in node_modules. It is common, it speeds up builds, and it does not weaken checks on your own code. Setting it to false now and then can reveal type conflicts between package versions, but you do not need it off permanently.

How does strict mode interact with Supabase generated types?

Types generated with supabase gen types typescript work with strict mode, and strict mode makes them more useful: with strictNullChecks, TypeScript flags every nullable column you read without checking it first.

Does enabling strict mode require rewriting existing code?

No rewrite, but you do have to address each error the compiler reports. Most fixes are small: a null check, a type annotation, optional chaining. Each one corresponds to a real potential runtime bug. Strict mode does not create problems; it shows you the ones already there.

Diagnose your codebase - free

VibeDoctor checks for CFG-007 and 148 other issues across 21 diagnostic areas - security, performance, code quality, and more.

SCAN MY APP →