@@ -7852,7 +7852,7 @@ namespace ts {
78527852 if (type && type.flags & TypeFlags.Union) {
78537853 let prop = getPropertyOfType(type, name);
78547854 if (!prop) {
7855- // The type may be a union that includes nullable or primtive types. If filtering
7855+ // The type may be a union that includes nullable or primitive types. If filtering
78567856 // those out produces a different type, get the property from that type instead.
78577857 // Effectively, we're checking if this *could* be a discriminant property once nullable
78587858 // and primitive types are removed by other type guards.
@@ -7915,10 +7915,10 @@ namespace ts {
79157915 // For example, when a variable of type number | string | boolean is assigned a value of type number | boolean,
79167916 // we remove type string.
79177917 function getAssignmentReducedType(declaredType: UnionType, assignedType: Type) {
7918- if (declaredType !== assignedType && declaredType.flags & TypeFlags.Union ) {
7919- const reducedTypes = filter (declaredType.types , t => typeMaybeAssignableTo(assignedType, t));
7920- if (reducedTypes.length ) {
7921- return reducedTypes.length === 1 ? reducedTypes[0] : getUnionType(reducedTypes) ;
7918+ if (declaredType !== assignedType) {
7919+ const reducedType = filterType (declaredType, t => typeMaybeAssignableTo(assignedType, t));
7920+ if (reducedType !== neverType ) {
7921+ return reducedType ;
79227922 }
79237923 }
79247924 return declaredType;
@@ -7992,26 +7992,7 @@ namespace ts {
79927992 }
79937993
79947994 function getTypeWithFacts(type: Type, include: TypeFacts) {
7995- if (!(type.flags & TypeFlags.Union)) {
7996- return getTypeFacts(type) & include ? type : neverType;
7997- }
7998- const types = (<UnionType>type).types;
7999- const length = types.length;
8000- let i = 0;
8001- while (i < length && getTypeFacts(types[i]) & include) i++;
8002- if (i === length) {
8003- return type;
8004- }
8005- const filtered = types.slice(0, i);
8006- i++;
8007- while (i < length) {
8008- const t = types[i];
8009- if (getTypeFacts(t) & include) {
8010- filtered.push(t);
8011- }
8012- i++;
8013- }
8014- return getUnionType(filtered);
7995+ return filterType(type, t => (getTypeFacts(t) & include) !== 0);
80157996 }
80167997
80177998 function getTypeWithDefault(type: Type, defaultExpression: Expression) {
@@ -8191,22 +8172,8 @@ namespace ts {
81918172 return f(type) ? type : neverType;
81928173 }
81938174 const types = (<UnionType>type).types;
8194- const length = types.length;
8195- let i = 0;
8196- while (i < length && f(types[i])) i++;
8197- if (i === length) {
8198- return type;
8199- }
8200- const filtered = types.slice(0, i);
8201- i++;
8202- while (i < length) {
8203- const t = types[i];
8204- if (f(t)) {
8205- filtered.push(t);
8206- }
8207- i++;
8208- }
8209- return getUnionType(filtered);
8175+ const filtered = filter(types, f);
8176+ return filtered === types ? type : getUnionType(filtered);
82108177 }
82118178
82128179 function isIncomplete(flowType: FlowType) {
@@ -8544,7 +8511,7 @@ namespace ts {
85448511 }
85458512 if (assumeTrue && !(type.flags & TypeFlags.Union)) {
85468513 // We narrow a non-union type to an exact primitive type if the non-union type
8547- // is a supertype of that primtive type. For example, type 'any' can be narrowed
8514+ // is a supertype of that primitive type. For example, type 'any' can be narrowed
85488515 // to one of the primitive types.
85498516 const targetType = getProperty(typeofTypesByName, literal.text);
85508517 if (targetType && isTypeSubtypeOf(targetType, type)) {
@@ -8633,9 +8600,9 @@ namespace ts {
86338600 // If the current type is a union type, remove all constituents that couldn't be instances of
86348601 // the candidate type. If one or more constituents remain, return a union of those.
86358602 if (type.flags & TypeFlags.Union) {
8636- const assignableConstituents = filter((<UnionType> type).types , t => isTypeInstanceOf(t, candidate));
8637- if (assignableConstituents.length ) {
8638- return getUnionType(assignableConstituents) ;
8603+ const assignableType = filterType( type, t => isTypeInstanceOf(t, candidate));
8604+ if (assignableType !== neverType ) {
8605+ return assignableType ;
86398606 }
86408607 }
86418608 // If the candidate type is a subtype of the target type, narrow to the candidate type.
0 commit comments