@@ -5919,6 +5919,13 @@ namespace ts {
59195919 return isTypeRelatedTo(source, target, assignableRelation);
59205920 }
59215921
5922+ // A type S is considered to be an instance of a type T if S and T are the same type or if S is a
5923+ // subtype of T but not structurally identical to T. This specifically means that two distinct but
5924+ // structurally identical types (such as two classes) are not considered instances of each other.
5925+ function isTypeInstanceOf(source: Type, target: Type): boolean {
5926+ return source === target || isTypeSubtypeOf(source, target) && !isTypeIdenticalTo(source, target);
5927+ }
5928+
59225929 /**
59235930 * This is *not* a bi-directional relationship.
59245931 * If one needs to check both directions for comparability, use a second call to this function or 'checkTypeComparableTo'.
@@ -8569,17 +8576,13 @@ namespace ts {
85698576 }
85708577
85718578 function getNarrowedType(type: Type, candidate: Type, assumeTrue: boolean) {
8572- // In the false branch we keep types that aren't subtypes of the candidate type and we keep structurally
8573- // identical types except for the current type itself. The latter rule means that given two structurally
8574- // identical classes A and B and a variable x of type A, in the false branch of an 'x instanceof B' type
8575- // guard x keeps type A and is not narrowed to type never.
85768579 if (!assumeTrue) {
8577- return filterType(type, t => !isTypeSubtypeOf (t, candidate) || isTypeIdenticalTo(t, candidate) && t !== candidate );
8580+ return filterType(type, t => !isTypeInstanceOf (t, candidate));
85788581 }
8579- // If the current type is a union type, remove all constituents that aren 't assignable to
8582+ // If the current type is a union type, remove all constituents that couldn 't be instances of
85808583 // the candidate type. If one or more constituents remain, return a union of those.
85818584 if (type.flags & TypeFlags.Union) {
8582- const assignableConstituents = filter((<UnionType>type).types, t => isTypeAssignableTo (t, candidate));
8585+ const assignableConstituents = filter((<UnionType>type).types, t => isTypeInstanceOf (t, candidate));
85838586 if (assignableConstituents.length) {
85848587 return getUnionType(assignableConstituents);
85858588 }
0 commit comments