@@ -9890,28 +9890,28 @@ namespace ts {
98909890 return links.resolvedType;
98919891 }
98929892
9893- function addTypeToIntersection(typeSet: Type[] , includes: TypeFlags, type: Type) {
9893+ function addTypeToIntersection(typeSet: Map< Type> , includes: TypeFlags, type: Type) {
98949894 const flags = type.flags;
98959895 if (flags & TypeFlags.Intersection) {
98969896 return addTypesToIntersection(typeSet, includes, (<IntersectionType>type).types);
98979897 }
98989898 if (isEmptyAnonymousObjectType(type)) {
98999899 if (!(includes & TypeFlags.IncludesEmptyObject)) {
99009900 includes |= TypeFlags.IncludesEmptyObject;
9901- typeSet.push( type);
9901+ typeSet.set(type.id.toString(), type);
99029902 }
99039903 }
99049904 else {
99059905 if (flags & TypeFlags.AnyOrUnknown) {
99069906 if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
99079907 }
9908- else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains( typeSet, type)) {
9908+ else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !typeSet.has( type.id.toString() )) {
99099909 if (type.flags & TypeFlags.Unit && includes & TypeFlags.Unit) {
99109910 // We have seen two distinct unit types which means we should reduce to an
99119911 // empty intersection. Adding TypeFlags.NonPrimitive causes that to happen.
99129912 includes |= TypeFlags.NonPrimitive;
99139913 }
9914- typeSet.push( type);
9914+ typeSet.set(type.id.toString(), type);
99159915 }
99169916 includes |= flags & TypeFlags.IncludesMask;
99179917 }
@@ -9920,7 +9920,7 @@ namespace ts {
99209920
99219921 // Add the given types to the given type set. Order is preserved, freshness is removed from literal
99229922 // types, duplicates are removed, and nested types of the given kind are flattened into the set.
9923- function addTypesToIntersection(typeSet: Type[] , includes: TypeFlags, types: ReadonlyArray<Type>) {
9923+ function addTypesToIntersection(typeSet: Map< Type> , includes: TypeFlags, types: ReadonlyArray<Type>) {
99249924 for (const type of types) {
99259925 includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(type));
99269926 }
@@ -10027,8 +10027,9 @@ namespace ts {
1002710027 // Also, unlike union types, the order of the constituent types is preserved in order that overload resolution
1002810028 // for intersections of types with signatures can be deterministic.
1002910029 function getIntersectionType(types: ReadonlyArray<Type>, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray<Type>): Type {
10030- const typeSet: Type[] = [];
10031- const includes = addTypesToIntersection(typeSet, 0, types);
10030+ const typeMembershipMap: Map<Type> = createMap();
10031+ const includes = addTypesToIntersection(typeMembershipMap, 0, types);
10032+ const typeSet: Type[] = arrayFrom(typeMembershipMap.values());
1003210033 // An intersection type is considered empty if it contains
1003310034 // the type never, or
1003410035 // more than one unit type or,
0 commit comments