A while back, I wrote about the experience of moving from raw JavaScript to
TypeScript. Usually, once a migration is done, a team inherits a tsconfig.json
that just "works" and a vague mandate from the lead to "make it as serious as
possible" or "set it to strict mode."
The issue is that being strict isn't just a single toggle. It’s a collection of
checks that, once turned on, can suddenly make your head spin. There are also
extra flags that aren't actually part of the strict: true package, but they
can be much more painful if they're suddenly activated.
I often feel that turning off strict mode just to "finish the migration quickly" is a huge mistake. Six months later, no one will remember which holes in the code were left there on purpose and which ones were actually bugs.
When we talk about strict: true, certain things hit you immediately. The one
that most often gets in the way is usually strictNullChecks. Suddenly, a
property you assumed would always be in your API response might actually be
null or undefined. Then there's noImplicitAny. The moment you leave a
function parameter untyped, TypeScript protests. Personally, I think this is
good—it forces our code to be more defined through a precise typing system.
However, there are other flags that have their downsides too. If you don't use them, you lose out, but if you turn them on too early, you might burn out.
Take noUncheckedIndexedAccess, for example. If this is on, every time you
access an array by its index, TypeScript forces you to assume the result might
be undefined. If you're building a list in React, code that used to be a
simple items[i].id suddenly turns entirely red. It’s very accurate, but
honestly, it’s incredibly annoying when you're chasing a deadline. I usually
wait to turn this on for critical domain logic—like money or permissions—rather
than experimental UI parts.
Then there's exactOptionalPropertyTypes. This is great for catching bugs when
we accidentally pass undefined through an object spread operator. In the React
world, where we do a lot of prop spreading, this flag can get very noisy.
One thing that often confuses me—and maybe you too—is the discrepancy between
what the editor says and what the terminal says. Sometimes my editor shows red
errors, but when I run it through CI or tsc --noEmit, everything is green.
As it turns out, the problem usually isn't the code itself, but how the toolchain reads our configuration. There are often three different readers in a single project that don't agree with each other. When that conflict happens, I tend to trust the CI results more.
At the end of the day, you don't have to solve everything with the strictest configuration overnight. There are times when you just need to blast ahead coding to move fast, but there are also times when you have to be disciplined so the code doesn't turn into a mess later on.
Catch you on the next one.