@@ -8855,39 +8855,46 @@ namespace ts {
8855
8855
return false;
8856
8856
}
8857
8857
8858
- function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) {
8858
+ function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type, noReduction: boolean ) {
8859
8859
const flags = type.flags;
8860
8860
if (flags & TypeFlags.Union) {
8861
- return addTypesToUnion(typeSet, includes, (<UnionType>type).types);
8861
+ return addTypesToUnion(typeSet, includes, (<UnionType>type).types, noReduction );
8862
8862
}
8863
8863
// We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are
8864
8864
// another form of 'never' (in that they have an empty value domain). We could in theory turn
8865
8865
// intersections of unit types into 'never' upon construction, but deferring the reduction makes it
8866
8866
// easier to reason about their origin.
8867
8867
if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(<IntersectionType>type))) {
8868
8868
includes |= flags & ~TypeFlags.ConstructionFlags;
8869
- if (flags & TypeFlags.AnyOrUnknown) {
8869
+ if (noReduction) {
8870
+ addTypeToTypeSet(typeSet, type);
8871
+ }
8872
+ else if (flags & TypeFlags.AnyOrUnknown) {
8870
8873
if (type === wildcardType) includes |= TypeFlags.Wildcard;
8871
8874
}
8872
8875
else if (!strictNullChecks && flags & TypeFlags.Nullable) {
8873
8876
if (!(flags & TypeFlags.ContainsWideningType)) includes |= TypeFlags.NonWideningType;
8874
8877
}
8875
8878
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);
8881
8880
}
8882
8881
}
8883
8882
return includes;
8884
8883
}
8885
8884
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
+
8886
8893
// Add the given types to the given type set. Order is preserved, duplicates are removed,
8887
8894
// 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 {
8889
8896
for (const type of types) {
8890
- includes = addTypeToUnion(typeSet, includes, type);
8897
+ includes = addTypeToUnion(typeSet, includes, type, noReduction );
8891
8898
}
8892
8899
return includes;
8893
8900
}
@@ -8964,24 +8971,26 @@ namespace ts {
8964
8971
return types[0];
8965
8972
}
8966
8973
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
+ }
8985
8994
}
8986
8995
return getUnionTypeFromSortedList(typeSet, includes & TypeFlags.NotPrimitiveUnion ? 0 : TypeFlags.UnionOfPrimitiveTypes, aliasSymbol, aliasTypeArguments);
8987
8996
}
@@ -16868,7 +16877,6 @@ namespace ts {
16868
16877
function getContextualTypeForElementExpression(arrayContextualType: Type | undefined, index: number): Type | undefined {
16869
16878
return arrayContextualType && (
16870
16879
getTypeOfPropertyOfContextualType(arrayContextualType, "" + index as __String)
16871
- || getIndexTypeOfContextualType(arrayContextualType, IndexKind.Number)
16872
16880
|| getIteratedTypeOrElementType(arrayContextualType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false, /*checkAssignability*/ false));
16873
16881
}
16874
16882
0 commit comments