@@ -7699,6 +7699,12 @@ namespace ts {
76997699 return source.flags & TypeFlags.Union ? !forEach((<UnionType>source).types, t => !contains(types, t)) : contains(types, source);
77007700 }
77017701
7702+ function filterType(type: Type, f: (t: Type) => boolean): Type {
7703+ return type.flags & TypeFlags.Union ?
7704+ getUnionType(filter((<UnionType>type).types, f)) :
7705+ f(type) ? type : neverType;
7706+ }
7707+
77027708 function getFlowTypeOfReference(reference: Node, declaredType: Type, assumeInitialized: boolean, includeOuterFunctions: boolean) {
77037709 let key: string;
77047710 if (!reference.flowNode || assumeInitialized && !(declaredType.flags & TypeFlags.Narrowable)) {
@@ -7944,7 +7950,7 @@ namespace ts {
79447950
79457951 function narrowTypeByDiscriminant(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
79467952 // We have '==', '!=', '===', or '!==' operator with property access on left
7947- if (!(type.flags & TypeFlags.Union) || ! isMatchingReference(reference, (<PropertyAccessExpression>expr.left).expression)) {
7953+ if (!isMatchingReference(reference, (<PropertyAccessExpression>expr.left).expression)) {
79487954 return type;
79497955 }
79507956 const propName = (<PropertyAccessExpression>expr.left).name.text;
@@ -7961,17 +7967,17 @@ namespace ts {
79617967 assumeTrue = !assumeTrue;
79627968 }
79637969 if (assumeTrue) {
7964- return getUnionType(filter((<UnionType> type).types , t => areTypesComparable(getTypeOfPropertyOfType(t, propName), discriminantType) ));
7970+ return filterType( type, t => areTypesComparable(getTypeOfPropertyOfType(t, propName), discriminantType));
79657971 }
79667972 if (discriminantType.flags & TypeFlags.StringLiteral) {
7967- return getUnionType(filter((<UnionType> type).types , t => getTypeOfPropertyOfType(t, propName) !== discriminantType) );
7973+ return filterType( type, t => getTypeOfPropertyOfType(t, propName) !== discriminantType);
79687974 }
79697975 return type;
79707976 }
79717977
79727978 function narrowTypeBySwitchOnDiscriminant(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number) {
79737979 // We have switch statement with property access expression
7974- if (!(type.flags & TypeFlags.Union) || ! isMatchingReference(reference, (<PropertyAccessExpression>switchStatement.expression).expression)) {
7980+ if (!isMatchingReference(reference, (<PropertyAccessExpression>switchStatement.expression).expression)) {
79757981 return type;
79767982 }
79777983 const propName = (<PropertyAccessExpression>switchStatement.expression).name.text;
@@ -7983,16 +7989,15 @@ namespace ts {
79837989 if (!switchTypes.length) {
79847990 return type;
79857991 }
7986- const types = (<UnionType>type).types;
79877992 const clauseTypes = switchTypes.slice(clauseStart, clauseEnd);
79887993 const hasDefaultClause = clauseStart === clauseEnd || contains(clauseTypes, undefined);
79897994 const caseTypes = hasDefaultClause ? filter(clauseTypes, t => !!t) : clauseTypes;
79907995 const discriminantType = caseTypes.length ? getUnionType(caseTypes) : undefined;
7991- const caseType = discriminantType && getUnionType(filter(types , t => isTypeComparableTo(discriminantType, getTypeOfPropertyOfType(t, propName) )));
7996+ const caseType = discriminantType && filterType(type , t => isTypeComparableTo(discriminantType, getTypeOfPropertyOfType(t, propName)));
79927997 if (!hasDefaultClause) {
79937998 return caseType;
79947999 }
7995- const defaultType = getUnionType(filter(types , t => !eachTypeContainedIn(getTypeOfPropertyOfType(t, propName), switchTypes) ));
8000+ const defaultType = filterType(type , t => !eachTypeContainedIn(getTypeOfPropertyOfType(t, propName), switchTypes));
79968001 return caseType ? getUnionType([caseType, defaultType]) : defaultType;
79978002 }
79988003
0 commit comments