DEV Community

YCM Jason
YCM Jason

Posted on

Introducing @ts-migrating: The Best Way To Upgrade Your TSConfig

πŸš€ TypeScript is evolving fast, and your tsconfig should keep up. But upgrading TypeScript settings like strict, noUncheckedIndexedAccess, or erasableSyntaxOnly often means dealing with hundreds of type errors across your codebase.

That’s why I built @ts-migrating, a plugin and CLI tool that helps you progressively upgrade your tsconfig.json without breaking your codebase or your team's velocity.

😩 The Pain of Upgrading tsconfig

When you switch on a stricter compiler option, you immediately see a flood of new type errors. It is overwhelming. Realistically, your team does not have the time to fix everything in one go, and trying to do so is a recipe for burnout and regressions.

So what do people do?

They either:

  • Delay the upgrade indefinitely
  • Use @ts-ignore or @ts-expect-error as a blanket patch

But both approaches are flawed. You either never improve your codebase, or you sweep problems under the rug, sometimes even hiding unrelated bugs.

🧠 A Better Way: @ts-migrating

@ts-migrating lets you enable your desired compiler options now, while allowing problematic lines to fall back to the old config. It is TypeScript migration reimagined:

  • Show type errors introduced by the new config
  • Patch only the lines that are not ready using // @ts-migrating
  • Gradually fix those lines and remove the fallbacks over time

This plugin is designed to be incremental and safe. In fact, that is why it is called @ts-migrating, emphasising the ongoing process, not a one off migration.

Unlike @ts-ignore, which silences all errors on a line and can mask unrelated problems, @ts-migrating targets only those errors introduced by the new compilerOptions. This makes the intent of the directive clear, and keeps the rest of the line type safe.

πŸ”Œ How It Works

To install, simply run:

npm install -D ts-migrating
Enter fullscreen mode Exit fullscreen mode

There are two parts to the tool:

1. Language Service Plugin

Add this to your tsconfig.json and your IDE will:

  • Show new errors introduced by the upgraded options
  • Allow you to silence specific lines with // @ts-migrating
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "ts-migrating",
        "compilerOptions": {
          "noUncheckedIndexedAccess": true
        }
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

This plugin only affects IDEs and development. It has no impact on tsc or production builds.

2. CLI Tooling

There are 2 main commands for the standalone CLI.

Type check with the plugin

Since ts plugins have no effect on tsc, you can instead use the following in your terminal / CI.

npx ts-migrating check
Enter fullscreen mode Exit fullscreen mode

This runs tsc with the plugin and reports all errors introduced by your new config.

Annotate your errors

npx ts-migrating annotate
Enter fullscreen mode Exit fullscreen mode

This will insert // @ts-migrating above every new error line. Be careful. Run with a clean git state and review the changes.

πŸ§ͺ Real Example: noUncheckedIndexedAccess

Here is a simple function:

function first(xs: number[]): number {
  return xs[0]; // error when `noUncheckedIndexedAccess: true`
}
Enter fullscreen mode Exit fullscreen mode

With @ts-migrating, we can temporarily allow this line to fall back:

function first(xs: number[]): number {
  // @ts-migrating
  return xs[0]; // error disappear as this line now fall back to `noUncheckedIndexedAccess: false`
}
Enter fullscreen mode Exit fullscreen mode

βœ… Why You Should Use It

  • Avoid big bang migrations
  • Prevent new violations from sneaking in
  • Let your team upgrade progressively
  • No build time impact
  • Clean, intentional code comments

🌟 Ready to Migrate?

ts-migrating helps you modernise your TypeScript setup without turning your codebase into a war zone.

You can find the project here:
πŸ‘‰ github.com/ycmjason/ts-migrating

If you like the idea, give the repo a star, try it in your project, and let me know how it goes.

And if you would like to support this work, consider becoming a GitHub Sponsor. Every bit helps.

Let us make tsconfig upgrades easy again.

Top comments (7)

Collapse
 
ben profile image
Ben Halpern

Looks great

Collapse
 
abstractalgo profile image
Dragan Okanovic • Edited

Very excited by the potential of this. ESlint has the option to progressively migrate rules by targeting only specific files with more strict rules, but this really has been a pain with TSconfig -- I'm not sure if this would be possible as an LSP plugin (to specify glob patterns that have different compiler options), but what ts-migrating is offering already is great (arguably even better). Thanks for the effort!

Collapse
 
nathan_tarbert profile image
Nathan Tarbert

this is honestly clutch for anyone dealing with tsconfig headaches, like finally an upgrade path that doesn’t wreck my whole week you think teams would start catching more subtle bugs if they used this kind of rollout

Collapse
 
ycmjason profile image
YCM Jason

from my experience, this approach really helps make sure new code introduced are enforced with new stricter ts config. and hence prevent obvious bugs that stricter type systems can catch. so ya i think this approach does help the team catch bugs earlier!!

Collapse
 
dotallio profile image
Dotallio

This is a game changer for incrementally tightening TS configs without chaos. Does @ts-migrating support custom rules or only the official compiler options?

Collapse
 
ycmjason profile image
YCM Jason

Which custom rules do you have in mind?

Collapse
 
nevodavid profile image
Nevo David

Been cool seeing steady progress like this - honestly, what do you think really keeps codebases improving long run? Slow habits or just showing up?