Pawk3k

Using TypeScript Strictly (Without Losing Your Mind)

Published on

TypeScript: The New Lingua Franca of the Web

It’s no secret anymore—TypeScript has become the default language of the modern web.

Like a famous man once said:

Everything that can be written in JavaScript will eventually be written in JavaScript.

And now, as we're seeing more and more:

Everything that can be written in JavaScript will eventually be written in TypeScript… and then transpiled to JavaScript.

We're not here to talk about how cool TypeScript is (even though, yeah, it totally is).
This is just me telling my story—and hopefully, you'll find something useful in it.


So… your team decided to use TypeScript?

You're probably thinking:
"OMG, finally! I'll get that sweet type-safety, and my daily coding life won't be such a pain anymore."

Your team struggled through the setup: figuring out the migration, adding a build step, picking a tool like vite or next, and finally… they renamed every *.js file to *.ts.

But somehow... nothing changed.
Bugs are still making it to production 💥.

You start wondering:
Was all this effort even worth it?
Was the time spent on integration just a huge waste?


Maybe you're not using TypeScript strict enough?

Here's the thing—TypeScript out of the box is nice.
But if you really want it to save you from bugs, you need to crank up the strictness.

Check your tsconfig.json:

json
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true
}
}

If those aren't enabled, you’re missing out on some of the best TypeScript has to offer.

Strict mode is how you prevent bugs before they ship.


Okay, so you turned on strict mode

And now you've got 100,000 TypeScript errors. Awesome. 😅

That’s not what you were hoping for, right?

You're using CI (…right? It’s 2025—please tell me you’re using CI), and now your pipeline is red. Not ideal.

So, what's the quick fix?

You could go around slapping @ts-ignore everywhere...
But please don’t do that.


Why @ts-ignore is a trap

Sure—it makes the error go away.
And yes, it means your new code will have to be written more carefully.

But using @ts-ignore is like saying:

“Hey TypeScript, shut up. I know better.”

You're silencing the compiler without any explanation.
Future you (or your teammates) won’t know why the error was ignored or if it’s even safe to touch.


A better way: @ts-expect-error (with context!)

Instead of muting the compiler entirely, use:

ts
// @ts-expect-error — This breaks because `foo` is possibly undefined
someFunction(foo.bar)

Why is this better?

  • You're saying: “I expect an error here. It’s fine… for now.”
  • If the error disappears (e.g. someone fixes the root cause), TypeScript will warn you that your @ts-expect-error is now invalid.
  • It leaves a human-readable trail. Anyone reading the code knows why this line was ignored.

So how do you handle this at scale?

Glad you asked.

If your codebase has thousands of errors, and you're not about to fix them all manually, check out this tool I built:

👉 @pawk3k/ts-migrator - JSR

Run it at the root of your repo, and it will automatically annotate your existing TypeScript errors with @ts-expect-error, including a reason where possible.

This way:

  • ✅ You keep your CI green
  • ❌ You don’t hide the problems
  • 🙌 You leave room to fix them later

Let me know if this helped—or if you’ve been through something similar. I’d love to hear your TypeScript war stories.

Happy migrating.