@@ -391,7 +391,7 @@ namespace ts {
391
391
392
392
const tupleTypes = createMap<GenericType>();
393
393
const unionTypes = createMap<UnionType>();
394
- const intersectionTypes = createMap<IntersectionType >();
394
+ const intersectionTypes = createMap<Type >();
395
395
const literalTypes = createMap<LiteralType>();
396
396
const indexedAccessTypes = createMap<IndexedAccessType>();
397
397
const substitutionTypes = createMap<SubstitutionType>();
@@ -9844,6 +9844,15 @@ namespace ts {
9844
9844
return true;
9845
9845
}
9846
9846
9847
+ function createIntersectionType(types: Type[], aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray<Type>) {
9848
+ const result = <IntersectionType>createType(TypeFlags.Intersection);
9849
+ result.objectFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable);
9850
+ result.types = types;
9851
+ result.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`.
9852
+ result.aliasTypeArguments = aliasTypeArguments;
9853
+ return result;
9854
+ }
9855
+
9847
9856
// We normalize combinations of intersection and union types based on the distributive property of the '&'
9848
9857
// operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection
9849
9858
// types with union type constituents into equivalent union types with intersection type constituents and
@@ -9881,31 +9890,31 @@ namespace ts {
9881
9890
if (typeSet.length === 1) {
9882
9891
return typeSet[0];
9883
9892
}
9884
- if (includes & TypeFlags.Union) {
9885
- if (intersectUnionsOfPrimitiveTypes(typeSet)) {
9886
- // When the intersection creates a reduced set (which might mean that *all* union types have
9887
- // disappeared), we restart the operation to get a new set of combined flags. Once we have
9888
- // reduced we'll never reduce again, so this occurs at most once.
9889
- return getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
9890
- }
9891
- // We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
9892
- // the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
9893
- const unionIndex = findIndex(typeSet, t => (t.flags & TypeFlags.Union) !== 0);
9894
- const unionType = <UnionType>typeSet[unionIndex];
9895
- return getUnionType(map(unionType.types, t => getIntersectionType(replaceElement(typeSet, unionIndex, t))),
9896
- UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
9897
- }
9898
9893
const id = getTypeListId(typeSet);
9899
- let type = intersectionTypes.get(id);
9900
- if (!type) {
9901
- type = <IntersectionType>createType(TypeFlags.Intersection);
9902
- intersectionTypes.set(id, type);
9903
- type.objectFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Nullable);
9904
- type.types = typeSet;
9905
- type.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`.
9906
- type.aliasTypeArguments = aliasTypeArguments;
9894
+ let result = intersectionTypes.get(id);
9895
+ if (!result) {
9896
+ if (includes & TypeFlags.Union) {
9897
+ if (intersectUnionsOfPrimitiveTypes(typeSet)) {
9898
+ // When the intersection creates a reduced set (which might mean that *all* union types have
9899
+ // disappeared), we restart the operation to get a new set of combined flags. Once we have
9900
+ // reduced we'll never reduce again, so this occurs at most once.
9901
+ result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
9902
+ }
9903
+ else {
9904
+ // We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
9905
+ // the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
9906
+ const unionIndex = findIndex(typeSet, t => (t.flags & TypeFlags.Union) !== 0);
9907
+ const unionType = <UnionType>typeSet[unionIndex];
9908
+ result = getUnionType(map(unionType.types, t => getIntersectionType(replaceElement(typeSet, unionIndex, t))),
9909
+ UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
9910
+ }
9911
+ }
9912
+ else {
9913
+ result = createIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
9914
+ }
9915
+ intersectionTypes.set(id, result);
9907
9916
}
9908
- return type ;
9917
+ return result ;
9909
9918
}
9910
9919
9911
9920
function getTypeFromIntersectionTypeNode(node: IntersectionTypeNode): Type {
0 commit comments