Reputation: 3043
Why does item instanceof TypeB === true
behave differently then item instanceof TypeB
and isTypeB(item) === true
behave differently then isTypeB(item)
where isTypeB(item): item is TypeB;
?
const items: (TypeA | TypeB)[] = [];
items.forEach(item => {
// instanceof explicit
if (item instanceof TypeB === true) {
// mouse over item -> TypeA | TypeB
doWithB(item); // red squiggly
}
// instanceof implicit
if (item instanceof TypeB) {
// mouse over item -> TypeB
doWithB(item);
}
// Type predicates explicit
if (isTypeB(item) === true) {
// mouse over item -> TypeA | TypeB
doWithB(item); // red squiggly
}
// Type predicates implicit
if (isTypeB(item)) {
// mouse over item -> TypeB
doWithB(item);
}
});
This should be the same logic and developer preference. Is this a Typescript bug?
https://stackblitz.com/edit/typescript-type-predicates-scope-with-explicit-bool?file=index.ts
Upvotes: 1
Views: 46
Reputation: 275917
Why does item instanceof TypeB === true behave differently then item instanceof TypeB
Simply because one is a valid type guard, whereas === true
is not a valid type guard. TypeScript doesn't try to be smart as you can always break it, e.g. here is a function that returns true
but changes state internally:
const assign = (): true => {
item = new TypeA();
return true;
}
// instanceof explicit
if ((item instanceof TypeB) === assign()) {
// mouse over item -> TypeA | TypeB
doWithB(item); // Aren't you glad its an error
}
Same for isTypeB(item) === true
.
TypeScript could make it valid, but isTypeB(item)
by itself already works, and a contrived example you want to work, is not going to become an error without justification on why you need to write code like that.
Upvotes: 2