@@ -8855,39 +8855,46 @@ namespace ts {
88558855 return false;
88568856 }
88578857
8858- function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) {
8858+ function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type, noReduction: boolean ) {
88598859 const flags = type.flags;
88608860 if (flags & TypeFlags.Union) {
8861- return addTypesToUnion(typeSet, includes, (<UnionType>type).types);
8861+ return addTypesToUnion(typeSet, includes, (<UnionType>type).types, noReduction );
88628862 }
88638863 // We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are
88648864 // another form of 'never' (in that they have an empty value domain). We could in theory turn
88658865 // intersections of unit types into 'never' upon construction, but deferring the reduction makes it
88668866 // easier to reason about their origin.
88678867 if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(<IntersectionType>type))) {
88688868 includes |= flags & ~TypeFlags.ConstructionFlags;
8869- if (flags & TypeFlags.AnyOrUnknown) {
8869+ if (noReduction) {
8870+ addTypeToTypeSet(typeSet, type);
8871+ }
8872+ else if (flags & TypeFlags.AnyOrUnknown) {
88708873 if (type === wildcardType) includes |= TypeFlags.Wildcard;
88718874 }
88728875 else if (!strictNullChecks && flags & TypeFlags.Nullable) {
88738876 if (!(flags & TypeFlags.ContainsWideningType)) includes |= TypeFlags.NonWideningType;
88748877 }
88758878 else {
8876- const len = typeSet.length;
8877- const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues);
8878- if (index < 0) {
8879- typeSet.splice(~index, 0, type);
8880- }
8879+ addTypeToTypeSet(typeSet, type);
88818880 }
88828881 }
88838882 return includes;
88848883 }
88858884
8885+ function addTypeToTypeSet(typeSet: Type[], type: Type) {
8886+ const len = typeSet.length;
8887+ const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues);
8888+ if (index < 0) {
8889+ typeSet.splice(~index, 0, type);
8890+ }
8891+ }
8892+
88868893 // Add the given types to the given type set. Order is preserved, duplicates are removed,
88878894 // and nested types of the given kind are flattened into the set.
8888- function addTypesToUnion(typeSet: Type[], includes: TypeFlags, types: ReadonlyArray<Type>): TypeFlags {
8895+ function addTypesToUnion(typeSet: Type[], includes: TypeFlags, types: ReadonlyArray<Type>, noReduction: boolean ): TypeFlags {
88898896 for (const type of types) {
8890- includes = addTypeToUnion(typeSet, includes, type);
8897+ includes = addTypeToUnion(typeSet, includes, type, noReduction );
88918898 }
88928899 return includes;
88938900 }
@@ -8964,24 +8971,26 @@ namespace ts {
89648971 return types[0];
89658972 }
89668973 const typeSet: Type[] = [];
8967- const includes = addTypesToUnion(typeSet, 0, types);
8968- if (includes & TypeFlags.AnyOrUnknown) {
8969- return includes & TypeFlags.Any ? includes & TypeFlags.Wildcard ? wildcardType : anyType : unknownType;
8970- }
8971- switch (unionReduction) {
8972- case UnionReduction.Literal:
8973- if (includes & TypeFlags.StringOrNumberLiteralOrUnique | TypeFlags.BooleanLiteral) {
8974- removeRedundantLiteralTypes(typeSet, includes);
8975- }
8976- break;
8977- case UnionReduction.Subtype:
8978- removeSubtypes(typeSet);
8979- break;
8980- }
8981- if (typeSet.length === 0) {
8982- return includes & TypeFlags.Null ? includes & TypeFlags.NonWideningType ? nullType : nullWideningType :
8983- includes & TypeFlags.Undefined ? includes & TypeFlags.NonWideningType ? undefinedType : undefinedWideningType :
8984- neverType;
8974+ const includes = addTypesToUnion(typeSet, 0, types, unionReduction === UnionReduction.None);
8975+ if (unionReduction !== UnionReduction.None) {
8976+ if (includes & TypeFlags.AnyOrUnknown) {
8977+ return includes & TypeFlags.Any ? includes & TypeFlags.Wildcard ? wildcardType : anyType : unknownType;
8978+ }
8979+ switch (unionReduction) {
8980+ case UnionReduction.Literal:
8981+ if (includes & TypeFlags.StringOrNumberLiteralOrUnique | TypeFlags.BooleanLiteral) {
8982+ removeRedundantLiteralTypes(typeSet, includes);
8983+ }
8984+ break;
8985+ case UnionReduction.Subtype:
8986+ removeSubtypes(typeSet);
8987+ break;
8988+ }
8989+ if (typeSet.length === 0) {
8990+ return includes & TypeFlags.Null ? includes & TypeFlags.NonWideningType ? nullType : nullWideningType :
8991+ includes & TypeFlags.Undefined ? includes & TypeFlags.NonWideningType ? undefinedType : undefinedWideningType :
8992+ neverType;
8993+ }
89858994 }
89868995 return getUnionTypeFromSortedList(typeSet, includes & TypeFlags.NotPrimitiveUnion ? 0 : TypeFlags.UnionOfPrimitiveTypes, aliasSymbol, aliasTypeArguments);
89878996 }
@@ -16868,7 +16877,6 @@ namespace ts {
1686816877 function getContextualTypeForElementExpression(arrayContextualType: Type | undefined, index: number): Type | undefined {
1686916878 return arrayContextualType && (
1687016879 getTypeOfPropertyOfContextualType(arrayContextualType, "" + index as __String)
16871- || getIndexTypeOfContextualType(arrayContextualType, IndexKind.Number)
1687216880 || getIteratedTypeOrElementType(arrayContextualType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false, /*checkAssignability*/ false));
1687316881 }
1687416882
0 commit comments