A while ago I introduced “strictNullChecks” into a largish Typescript code base.
A bumpy ride, but I got along well. Most available 3rd party typings were right
with regards to
undefined; most compiler errors were just a matter
of putting an
if in place or adding
undefined to type declarations.
Then I got stuck at the following line:
Looks innocent, eh?
render came from an NPM dependency whose typings
said that the argument was not nullable1.
D’oh. I didn’t know this part of our code base, nor the library in question, so I couldn’t come up with any obvious non-null value to use. And neither did I have the time to go deep down the rabbit hole and start refactoring.
Browsing through the Typescript manual I found an abomination that goes by the innocent name “type assertion operator”. This… thing eliminiates “null” from expression types by mesmerizing the compiler into believing that a happy unicorn guards the expression, fighting off all evil nulls so that the expression can never ever result in null no matter what those stupid ignorant types say.
So… you see where this is going:
null!—here we are, convincing the Typescript compiler that null is, in fact, not null.
An epitome of unsoundness.
Ironically, that’s closer to the truth. While the library indeed accepts↩︎
nullin this place, it’s not documented anywhere and the corresponding null check is deep down the call tree in some private function and looks like a quick & dirty bug fix hack. So yeah, we shouldn’t pass null here, but that’s what the consultant who introduced that lib did so who am I to judge?