Legacy TypeScript codebases without strict mode are everywhere. The migration looks scary — thousands of errors light up the moment you flip the flag — but it's straightforward if you do it incrementally and use the AI tools that actually work in 2026. Here's the order, the tools, and what to skip.
What changed in 2026
- TypeScript 5.5 introduced inferred type predicates and other strict-mode-easing features.
- AI codemods (Claude / Cursor agents) handle the bulk of trivial fixes. Time savings is 5-10x vs hand-edits.
expect-type and vitest make testing type-level changes easier.
The flag order
Don't toggle strict: true and stare at 8,000 errors. Enable individual flags in this order:
1. noImplicitAny — usually the easiest. Wherever TS can't infer, you must annotate. Auto-fixable about 80% of the time with AI codemods.
2. strictNullChecks — the painful one. Now string | null and string are different types. Expect 50-70% of total migration work to be here. Worth it: this flag prevents the largest class of real production bugs.
3. strictFunctionTypes — function-parameter contravariance. Usually a handful of errors, easy fixes.
4. noImplicitReturns — every code path must return something explicit. Adds discipline; minor effort.
5. strictBindCallApply — type-checks .bind(), .call(), .apply(). Trivial for most codebases.
6. strictPropertyInitialization — class properties must be initialized. Usually requires definite assignment assertion (!) for fields set in useEffect-style patterns.
The AI-assisted migration workflow
For each flag:
- Enable the flag in
tsconfig.json.
- Run
tsc --noEmit and capture all errors to a file.
- Group errors by file.
- Pass error groups to Claude or Cursor with: "Fix these TypeScript strict-mode errors. Don't change behavior. Mark anything ambiguous with a TODO."
- Run tests after each batch.
- Don't enable the next flag until all errors from the previous are resolved.
This pipeline gets you 80%+ auto-fix rate. The remaining 20% are the cases where the human (or a more careful AI pass) needs to actually decide what the code should do.
Block regressions in CI
The minute you start the migration, add --noEmitOnError in your build step or run tsc --noEmit in a required CI check. Otherwise, every PR while you're migrating will add fresh strict-mode violations. The check should be set per directory or per file pattern as you migrate, not all-at-once.
Comparison: migration approaches in 2026
| Approach |
Time (10k LOC) |
Quality |
Best for |
| Flag-by-flag, AI-assisted |
1-3 days |
High |
Most teams |
| Big-bang, hand-fix |
2-4 weeks |
Variable |
Small codebases |
File-by-file with // @ts-strict |
4-8 weeks |
High |
Massive monorepos |
| Hire a contractor |
1-2 weeks |
High |
When the team can't pause |
Common mistakes to avoid
Casting to any to make errors disappear. You've thrown away the safety this migration is trying to gain. If you must escape, use unknown and explicit narrowing.
Skipping strictNullChecks. It's the painful flag, but it's also the one that catches real bugs. Don't half-migrate.
Not pinning the TS version. Strict-mode behavior subtly changes across TS minors. Pin during migration.
Trying to perfect types instead of preserving behavior. First pass is "make it compile". Second pass is "tighten types properly".
Suppressing whole files with // @ts-nocheck. It works as triage, but tracks tech debt; build a backlog of files to revisit.
FAQ
Should I enable noUncheckedIndexedAccess?
Yes, eventually. It's not part of strict but catches a lot of array/object access bugs. Save it for after the strict flags.
What about exactOptionalPropertyTypes?
Strict in spirit but not in strict: true. Mixed reception in the community; consider for new projects, skip for migrations.
Is unknown always better than any?
Yes. unknown requires narrowing at the use site; any skips type-checking entirely. The narrowing forces explicit handling.
Will strict mode slow my builds?
Minor — single-digit % typically. Not a real concern.
Where to go next
For related guides see Next.js 15 Server Actions guide for 2026, Vitest vs Jest in 2026, and Drizzle vs Prisma in 2026.