I was under the impression that a type guard which takes multiple types instanceOfA(arg: A | B | C): arg is A, would narrow the type to either A (when the guard returns true) or B | C (when the guard returns false)
However in the case of instanceOfB below, returning false seem to narrow the type to never, while true doesn't narrow it at all. Do type guards in fact only narrow the type if true is returned? Or am I misunderstanding the results, in which case, why does the narrowing to never occur?
// Structures
interface A {
value: string
children: B[]
}
interface B {
value: string
}
// Example functions
function doSomething1(arg: A | B) {
if (instanceOfA(arg)) {
console.log(`A: ${arg.value}`) // Type of arg is A
} else {
console.log(`B: ${arg.value}`) // Type of arg is B
}
}
function doSomething2(arg: A | B) {
if (instanceOfB(arg)) {
console.log(`B: ${arg.value}`) // Type of arg is A | B
} else {
console.log(`A: ${arg.value}`) // Type of arg is never
}
}
// Typeguards
function instanceOfA(ab: A | B): ab is A {
return ab.hasOwnProperty('children')
}
function instanceOfB(ab: A | B): ab is B {
return !ab.hasOwnProperty('children')
}