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