The recent updates in version 4.9 highlighted the enhanced narrowing with 'in'. Intrigued by this, I decided to experiment with their example in a coding playground. Surprisingly, I discovered that seemingly impossible conditions involving typeof
and in
were being narrowed down to never
without triggering any warnings or errors:
// Shouldn't this be flagged as illegal?
if (typeof packageJSON.name === "string" && typeof packageJSON.name === "number") {
I assumed that TypeScript would recognize that packageJSON.name
is always a string, making it illogical to check if its type is also a number. However, even attempting to compare literals didn't prompt TypeScript to raise any issues:
typeof 123 === "string" // Surprisingly no error raised here either?
A similar inconsistency was observed with the usage of in
:
// How can it simultaneously have and lack the "name" key?
if (packageJSON && typeof packageJSON === "object" && "name" in packageJSON && !("name" in packageJSON)) {
While I acknowledge that the types are correctly narrowed to never
, I had expected TypeScript to warn me about employing impossible conditions. Notably, TypeScript already does this for equality checks:
// TypeScript understands that packageJSON cannot be both 0 and 1
if (packageJSON === 0 && packageJSON === 1) {
This behavior left me puzzled. Is it intentional or a limitation? How can I prevent or receive alerts about such scenarios (possibly through a linter)? You can access the code samples discussed above in this playground link.