π 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
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
}
}
]
}
}
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
This runs tsc
with the plugin and reports all errors introduced by your new config.
Annotate your errors
npx ts-migrating annotate
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`
}
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`
}
β 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)
Looks great
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!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
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!!
This is a game changer for incrementally tightening TS configs without chaos. Does @ts-migrating support custom rules or only the official compiler options?
Which custom rules do you have in mind?
Been cool seeing steady progress like this - honestly, what do you think really keeps codebases improving long run? Slow habits or just showing up?