A while ago I introduced “strictNullChecks” into a largish Typescript code base.
A bumpy ride, but I got along quite well. Available 3rd party typings were
surprisingly accurate with regards to
undefined; most compiler
errors were just a matter of putting an
if in place or adding
undefined to type declarations.
But then I got stuck at the following line:
Looks innocent, eh? Unfortunately
render came from an NPM dependency… whose
typings said that the argument was not nullable, of course1.
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 an expression is guarded by a happy unicorn 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 suspiciously like a quick & dirty bug fix hack. So yeah, we probably shouldn’t pass null here, but that’s what the consultant who introduced that lib did so who am I to judge? ↩