Let's consider this simple statement :
var foo = document.getElementById('foo');
if (foo instanceof Element) {
a.innerHTML = "Some text";
}
But if you write :
var foo = document.getElementById('foo');
if (foo instanceof Element === true) {
a.innerHTML = "Some text";
}
The TypeScript transpiler throws an error :
'foo' is possibly 'null'.
Assuming that instanceof can return only true of false, I don't see why the transpiler doesn't accept the condition with === true. Same error with the opposite statement :
!(foo instanceof Element)
is not the same than :
foo instanceof Element === false
What is the reason of this behaviour ? Is there any difference between the 2 statements ?
TypeScript's narrowing / type guarding support only applies to certain coding patterns. The type checker cannot afford to analyze code by simulating every possible logical implication of the code flow; instead it uses heuristics to detect common conventions that are used in practice as type guards. They have to be common, so that the benefits of narrowing outweigh the cost incurred by performing additional checks everywhere. (See this unpopular comment by the TS team dev lead on microsoft/TypeScript#26275, for example.)
There's an older issue at microsoft/TypeScript#9508 where it is proposed that expr === true
and expr === false
behave as type guards in the same situations where expr
and !expr
would behave as type guards. This was closed as "won't fix" because "in most cases === true
is a code smell and doesn't appear often enough to justify the extra complexity to support it."
On the other hand, there's an issue at microsoft/TypeSript#31105 asking for the same thing, and it's marked as a bug. It's on the Backlog, meaning that nobody is necessarily going to work on it. However, the TS folks are often receptive to accepting pull requests from the community for such Backlog issues, so that means the best way to see this change would be for an interested party to submit an appropriate pull request.
Until and unless such support is implemented, the easiest way to proceed is to simply perform the more conventional checks of expr
and !expr
, like if (foo instanceof Element)
or if (!(foo instanceof Element))
. Anything else would be more complicated or fragile (e.g., writing a custom type guard function)