@@ -15310,7 +15310,7 @@ namespace ts {
15310
15310
objectFlags & ObjectFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeVariables) ||
15311
15311
objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations ||
15312
15312
objectFlags & ObjectFlags.Mapped ||
15313
- type.flags & TypeFlags.UnionOrIntersection && couldUnionOrIntersectionContainTypeVariables(<UnionOrIntersectionType>type));
15313
+ type.flags & TypeFlags.UnionOrIntersection && !(type.flags & TypeFlags.EnumLiteral) && couldUnionOrIntersectionContainTypeVariables(<UnionOrIntersectionType>type));
15314
15314
}
15315
15315
15316
15316
function couldUnionOrIntersectionContainTypeVariables(type: UnionOrIntersectionType): boolean {
@@ -15487,37 +15487,47 @@ namespace ts {
15487
15487
inferFromTypeArguments(source.aliasTypeArguments, target.aliasTypeArguments!, getAliasVariances(source.aliasSymbol));
15488
15488
return;
15489
15489
}
15490
- if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union && !(source.flags & TypeFlags.EnumLiteral && target.flags & TypeFlags.EnumLiteral) ||
15491
- source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
15492
- // Source and target are both unions or both intersections. If source and target
15493
- // are the same type, just relate each constituent type to itself.
15494
- if (source === target) {
15495
- for (const t of (<UnionOrIntersectionType>source).types) {
15496
- inferFromTypes(t, t);
15490
+ if (source === target && source.flags & TypeFlags.UnionOrIntersection) {
15491
+ // When source and target are the same union or intersection type, just relate each constituent
15492
+ // type to itself.
15493
+ for (const t of (<UnionOrIntersectionType>source).types) {
15494
+ inferFromTypes(t, t);
15495
+ }
15496
+ return;
15497
+ }
15498
+ if (target.flags & TypeFlags.Union) {
15499
+ if (source.flags & TypeFlags.Union) {
15500
+ // First, infer between identically matching source and target constituents and remove the
15501
+ // matching types.
15502
+ const [tempSources, tempTargets] = inferFromMatchingTypes((<UnionType>source).types, (<UnionType>target).types, isTypeOrBaseIdenticalTo);
15503
+ // Next, infer between closely matching source and target constituents and remove
15504
+ // the matching types. Types closely match when they are instantiations of the same
15505
+ // object type or instantiations of the same type alias.
15506
+ const [sources, targets] = inferFromMatchingTypes(tempSources, tempTargets, isTypeCloselyMatchedBy);
15507
+ if (sources.length === 0 || targets.length === 0) {
15508
+ return;
15497
15509
}
15498
- return;
15510
+ source = getUnionType(sources);
15511
+ target = getUnionType(targets);
15499
15512
}
15500
- // First, infer between exactly matching source and target constituents and remove
15501
- // the matching types. Types exactly match when they are identical or, in union
15502
- // types, when the source is a literal and the target is the corresponding primitive.
15503
- const matching = target.flags & TypeFlags.Union ? isTypeOrBaseIdenticalTo : isTypeIdenticalTo;
15504
- const [tempSources, tempTargets] = inferFromMatchingTypes((<UnionOrIntersectionType>source).types, (<UnionOrIntersectionType>target).types, matching);
15505
- // Next, infer between closely matching source and target constituents and remove
15506
- // the matching types. Types closely match when they are instantiations of the same
15507
- // object type or instantiations of the same type alias.
15508
- const [sources, targets] = inferFromMatchingTypes(tempSources, tempTargets, isTypeCloselyMatchedBy);
15509
- if (sources.length === 0 || targets.length === 0) {
15510
- return;
15513
+ else {
15514
+ if (inferFromMatchingType(source, (<UnionType>target).types, isTypeOrBaseIdenticalTo)) return;
15515
+ if (inferFromMatchingType(source, (<UnionType>target).types, isTypeCloselyMatchedBy)) return;
15511
15516
}
15512
- source = source.flags & TypeFlags.Union ? getUnionType(sources) : getIntersectionType(sources);
15513
- target = target.flags & TypeFlags.Union ? getUnionType(targets) : getIntersectionType(targets);
15514
15517
}
15515
- else if (target.flags & TypeFlags.Union && !(target.flags & TypeFlags.EnumLiteral) || target.flags & TypeFlags.Intersection) {
15516
- // This block of code is an optimized version of the block above for the simpler case
15517
- // of a singleton source type.
15518
- const matching = target.flags & TypeFlags.Union ? isTypeOrBaseIdenticalTo : isTypeIdenticalTo;
15519
- if (inferFromMatchingType(source, (<UnionOrIntersectionType>target).types, matching)) return;
15520
- if (inferFromMatchingType(source, (<UnionOrIntersectionType>target).types, isTypeCloselyMatchedBy)) return;
15518
+ else if (target.flags & TypeFlags.Intersection && some((<IntersectionType>target).types, t => !!getInferenceInfoForType(t))) {
15519
+ if (source.flags & TypeFlags.Intersection) {
15520
+ // Infer between identically matching source and target constituents and remove the matching types.
15521
+ const [sources, targets] = inferFromMatchingTypes((<IntersectionType>source).types, (<IntersectionType>target).types, isTypeIdenticalTo);
15522
+ if (sources.length === 0 || targets.length === 0) {
15523
+ return;
15524
+ }
15525
+ source = getIntersectionType(sources);
15526
+ target = getIntersectionType(targets);
15527
+ }
15528
+ else if (!(source.flags & TypeFlags.Union)) {
15529
+ if (inferFromMatchingType(source, (<IntersectionType>target).types, isTypeIdenticalTo)) return;
15530
+ }
15521
15531
}
15522
15532
else if (target.flags & (TypeFlags.IndexedAccess | TypeFlags.Substitution)) {
15523
15533
target = getActualTypeVariable(target);
0 commit comments