@@ -618,22 +618,6 @@ namespace ts {
618
618
Both = Source | Target,
619
619
}
620
620
621
- const enum TypeIncludes {
622
- Any = 1 << 0,
623
- Undefined = 1 << 1,
624
- Null = 1 << 2,
625
- Never = 1 << 3,
626
- NonWideningType = 1 << 4,
627
- String = 1 << 5,
628
- Number = 1 << 6,
629
- ESSymbol = 1 << 7,
630
- LiteralOrUniqueESSymbol = 1 << 8,
631
- ObjectType = 1 << 9,
632
- EmptyObject = 1 << 10,
633
- Union = 1 << 11,
634
- Wildcard = 1 << 12,
635
- }
636
-
637
621
const enum MembersOrExportsResolutionKind {
638
622
resolvedExports = "resolvedExports",
639
623
resolvedMembers = "resolvedMembers"
@@ -8047,35 +8031,31 @@ namespace ts {
8047
8031
return false;
8048
8032
}
8049
8033
8050
- function addTypeToUnion(typeSet: Type[], includes: TypeIncludes , type: Type) {
8034
+ function addTypeToUnion(typeSet: Type[], includes: TypeFlags , type: Type) {
8051
8035
const flags = type.flags;
8052
8036
if (flags & TypeFlags.Union) {
8053
- includes = addTypesToUnion(typeSet, includes, (<UnionType>type).types);
8054
- }
8055
- else if (flags & TypeFlags.Any) {
8056
- includes |= TypeIncludes.Any;
8057
- if (type === wildcardType) includes |= TypeIncludes.Wildcard;
8058
- }
8059
- else if (!strictNullChecks && flags & TypeFlags.Nullable) {
8060
- if (flags & TypeFlags.Undefined) includes |= TypeIncludes.Undefined;
8061
- if (flags & TypeFlags.Null) includes |= TypeIncludes.Null;
8062
- if (!(flags & TypeFlags.ContainsWideningType)) includes |= TypeIncludes.NonWideningType;
8063
- }
8064
- else if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(<IntersectionType>type))) {
8065
- // We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are
8066
- // another form of 'never' (in that they have an empty value domain). We could in theory turn
8067
- // intersections of unit types into 'never' upon construction, but deferring the reduction makes it
8068
- // easier to reason about their origin.
8069
- if (flags & TypeFlags.String) includes |= TypeIncludes.String;
8070
- if (flags & TypeFlags.Number) includes |= TypeIncludes.Number;
8071
- if (flags & TypeFlags.ESSymbol) includes |= TypeIncludes.ESSymbol;
8072
- if (flags & TypeFlags.StringOrNumberLiteralOrUnique) includes |= TypeIncludes.LiteralOrUniqueESSymbol;
8073
- const len = typeSet.length;
8074
- const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues);
8075
- if (index < 0) {
8076
- if (!(flags & TypeFlags.Object && (<ObjectType>type).objectFlags & ObjectFlags.Anonymous &&
8077
- type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) {
8078
- typeSet.splice(~index, 0, type);
8037
+ return addTypesToUnion(typeSet, includes, (<UnionType>type).types);
8038
+ }
8039
+ // We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are
8040
+ // another form of 'never' (in that they have an empty value domain). We could in theory turn
8041
+ // intersections of unit types into 'never' upon construction, but deferring the reduction makes it
8042
+ // easier to reason about their origin.
8043
+ if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(<IntersectionType>type))) {
8044
+ includes |= flags & ~TypeFlags.ConstructionFlags;
8045
+ if (flags & TypeFlags.Any) {
8046
+ if (type === wildcardType) includes |= TypeFlags.Wildcard;
8047
+ }
8048
+ else if (!strictNullChecks && flags & TypeFlags.Nullable) {
8049
+ if (!(flags & TypeFlags.ContainsWideningType)) includes |= TypeFlags.NonWideningType;
8050
+ }
8051
+ else {
8052
+ const len = typeSet.length;
8053
+ const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues);
8054
+ if (index < 0) {
8055
+ if (!(flags & TypeFlags.Object && (<ObjectType>type).objectFlags & ObjectFlags.Anonymous &&
8056
+ type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) {
8057
+ typeSet.splice(~index, 0, type);
8058
+ }
8079
8059
}
8080
8060
}
8081
8061
}
@@ -8084,7 +8064,7 @@ namespace ts {
8084
8064
8085
8065
// Add the given types to the given type set. Order is preserved, duplicates are removed,
8086
8066
// and nested types of the given kind are flattened into the set.
8087
- function addTypesToUnion(typeSet: Type[], includes: TypeIncludes , types: Type[]): TypeIncludes {
8067
+ function addTypesToUnion(typeSet: Type[], includes: TypeFlags , types: Type[]): TypeFlags {
8088
8068
for (const type of types) {
8089
8069
includes = addTypeToUnion(typeSet, includes, type);
8090
8070
}
@@ -8141,15 +8121,15 @@ namespace ts {
8141
8121
}
8142
8122
}
8143
8123
8144
- function removeRedundantLiteralTypes(types: Type[], includes: TypeIncludes ) {
8124
+ function removeRedundantLiteralTypes(types: Type[], includes: TypeFlags ) {
8145
8125
let i = types.length;
8146
8126
while (i > 0) {
8147
8127
i--;
8148
8128
const t = types[i];
8149
8129
const remove =
8150
- t.flags & TypeFlags.StringLiteral && includes & TypeIncludes .String ||
8151
- t.flags & TypeFlags.NumberLiteral && includes & TypeIncludes .Number ||
8152
- t.flags & TypeFlags.UniqueESSymbol && includes & TypeIncludes .ESSymbol ||
8130
+ t.flags & TypeFlags.StringLiteral && includes & TypeFlags .String ||
8131
+ t.flags & TypeFlags.NumberLiteral && includes & TypeFlags .Number ||
8132
+ t.flags & TypeFlags.UniqueESSymbol && includes & TypeFlags .ESSymbol ||
8153
8133
t.flags & TypeFlags.StringOrNumberLiteral && t.flags & TypeFlags.FreshLiteral && containsType(types, (<LiteralType>t).regularType);
8154
8134
if (remove) {
8155
8135
orderedRemoveItemAt(types, i);
@@ -8173,12 +8153,12 @@ namespace ts {
8173
8153
}
8174
8154
const typeSet: Type[] = [];
8175
8155
const includes = addTypesToUnion(typeSet, 0, types);
8176
- if (includes & TypeIncludes .Any) {
8177
- return includes & TypeIncludes .Wildcard ? wildcardType : anyType;
8156
+ if (includes & TypeFlags .Any) {
8157
+ return includes & TypeFlags .Wildcard ? wildcardType : anyType;
8178
8158
}
8179
8159
switch (unionReduction) {
8180
8160
case UnionReduction.Literal:
8181
- if (includes & TypeIncludes.LiteralOrUniqueESSymbol ) {
8161
+ if (includes & TypeFlags.StringOrNumberLiteralOrUnique ) {
8182
8162
removeRedundantLiteralTypes(typeSet, includes);
8183
8163
}
8184
8164
break;
@@ -8187,8 +8167,8 @@ namespace ts {
8187
8167
break;
8188
8168
}
8189
8169
if (typeSet.length === 0) {
8190
- return includes & TypeIncludes .Null ? includes & TypeIncludes .NonWideningType ? nullType : nullWideningType :
8191
- includes & TypeIncludes .Undefined ? includes & TypeIncludes .NonWideningType ? undefinedType : undefinedWideningType :
8170
+ return includes & TypeFlags .Null ? includes & TypeFlags .NonWideningType ? nullType : nullWideningType :
8171
+ includes & TypeFlags .Undefined ? includes & TypeFlags .NonWideningType ? undefinedType : undefinedWideningType :
8192
8172
neverType;
8193
8173
}
8194
8174
return getUnionTypeFromSortedList(typeSet, aliasSymbol, aliasTypeArguments);
@@ -8266,30 +8246,23 @@ namespace ts {
8266
8246
return links.resolvedType;
8267
8247
}
8268
8248
8269
- function addTypeToIntersection(typeSet: Type[], includes: TypeIncludes , type: Type) {
8249
+ function addTypeToIntersection(typeSet: Type[], includes: TypeFlags , type: Type) {
8270
8250
const flags = type.flags;
8271
8251
if (flags & TypeFlags.Intersection) {
8272
- includes = addTypesToIntersection(typeSet, includes, (<IntersectionType>type).types);
8273
- }
8274
- else if (flags & TypeFlags.Any) {
8275
- includes |= TypeIncludes.Any;
8276
- if (type === wildcardType) includes |= TypeIncludes.Wildcard;
8277
- }
8278
- else if (flags & TypeFlags.Never) {
8279
- includes |= TypeIncludes.Never;
8252
+ return addTypesToIntersection(typeSet, includes, (<IntersectionType>type).types);
8280
8253
}
8281
- else if (getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type)) {
8282
- includes |= TypeIncludes .EmptyObject;
8254
+ if (getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type)) {
8255
+ includes |= TypeFlags .EmptyObject;
8283
8256
}
8284
- else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type)) {
8285
- if ( flags & TypeFlags.Object) {
8286
- includes |= TypeIncludes.ObjectType;
8287
- }
8288
- if (flags & TypeFlags.Union) {
8289
- includes |= TypeIncludes.Union;
8290
- }
8291
- if (!(flags & TypeFlags.Object && (<ObjectType> type).objectFlags & ObjectFlags.Anonymous &&
8292
- type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) {
8257
+ else {
8258
+ includes |= flags & ~ TypeFlags.ConstructionFlags;
8259
+ if (flags & TypeFlags.Any) {
8260
+ if (type === wildcardType) includes |= TypeFlags.Wildcard;
8261
+ }
8262
+ else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type) &&
8263
+ !(flags & TypeFlags.Object && (<ObjectType>type).objectFlags & ObjectFlags.Anonymous &&
8264
+ type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) &&
8265
+ containsIdenticalType(typeSet, type))) {
8293
8266
typeSet.push(type);
8294
8267
}
8295
8268
}
@@ -8298,13 +8271,28 @@ namespace ts {
8298
8271
8299
8272
// Add the given types to the given type set. Order is preserved, freshness is removed from literal
8300
8273
// types, duplicates are removed, and nested types of the given kind are flattened into the set.
8301
- function addTypesToIntersection(typeSet: Type[], includes: TypeIncludes , types: Type[]) {
8274
+ function addTypesToIntersection(typeSet: Type[], includes: TypeFlags , types: Type[]) {
8302
8275
for (const type of types) {
8303
8276
includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(type));
8304
8277
}
8305
8278
return includes;
8306
8279
}
8307
8280
8281
+ function removeRedundantPrimitiveTypes(types: Type[], includes: TypeFlags) {
8282
+ let i = types.length;
8283
+ while (i > 0) {
8284
+ i--;
8285
+ const t = types[i];
8286
+ const remove =
8287
+ t.flags & TypeFlags.String && includes & TypeFlags.StringLiteral ||
8288
+ t.flags & TypeFlags.Number && includes & TypeFlags.NumberLiteral ||
8289
+ t.flags & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol;
8290
+ if (remove) {
8291
+ orderedRemoveItemAt(types, i);
8292
+ }
8293
+ }
8294
+ }
8295
+
8308
8296
// We normalize combinations of intersection and union types based on the distributive property of the '&'
8309
8297
// operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection
8310
8298
// types with union type constituents into equivalent union types with intersection type constituents and
@@ -8321,19 +8309,24 @@ namespace ts {
8321
8309
}
8322
8310
const typeSet: Type[] = [];
8323
8311
const includes = addTypesToIntersection(typeSet, 0, types);
8324
- if (includes & TypeIncludes .Never) {
8312
+ if (includes & TypeFlags .Never) {
8325
8313
return neverType;
8326
8314
}
8327
- if (includes & TypeIncludes.Any) {
8328
- return includes & TypeIncludes.Wildcard ? wildcardType : anyType;
8315
+ if (includes & TypeFlags.Any) {
8316
+ return includes & TypeFlags.Wildcard ? wildcardType : anyType;
8317
+ }
8318
+ if (includes & TypeFlags.String && includes & TypeFlags.StringLiteral ||
8319
+ includes & TypeFlags.Number && includes & TypeFlags.NumberLiteral ||
8320
+ includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol) {
8321
+ removeRedundantPrimitiveTypes(typeSet, includes);
8329
8322
}
8330
- if (includes & TypeIncludes .EmptyObject && !(includes & TypeIncludes.ObjectType )) {
8323
+ if (includes & TypeFlags .EmptyObject && !(includes & TypeFlags.Object )) {
8331
8324
typeSet.push(emptyObjectType);
8332
8325
}
8333
8326
if (typeSet.length === 1) {
8334
8327
return typeSet[0];
8335
8328
}
8336
- if (includes & TypeIncludes .Union) {
8329
+ if (includes & TypeFlags .Union) {
8337
8330
// We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
8338
8331
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
8339
8332
const unionIndex = findIndex(typeSet, t => (t.flags & TypeFlags.Union) !== 0);
0 commit comments