Improve reduction of similar intersections in type inference (#51405)

* Change criteria for reducing intersections in type inference

* Add regression test
This commit is contained in:
Anders Hejlsberg
2022-11-04 17:04:05 -07:00
committed by GitHub
parent f1d62f4dc4
commit f0216e3421
5 changed files with 51 additions and 6 deletions

View File

@@ -22728,14 +22728,11 @@ namespace ts {
}
source = getUnionType(sources);
}
else if (target.flags & TypeFlags.Intersection && some((target as IntersectionType).types,
t => !!getInferenceInfoForType(t) || (isGenericMappedType(t) && !!getInferenceInfoForType(getHomomorphicTypeVariable(t) || neverType)))) {
// We reduce intersection types only when they contain naked type parameters. For example, when
// inferring from 'string[] & { extra: any }' to 'string[] & T' we want to remove string[] and
else if (target.flags & TypeFlags.Intersection && !every((target as IntersectionType).types, isNonGenericObjectType)) {
// We reduce intersection types unless they're simple combinations of object types. For example,
// when inferring from 'string[] & { extra: any }' to 'string[] & T' we want to remove string[] and
// infer { extra: any } for T. But when inferring to 'string[] & Iterable<T>' we want to keep the
// string[] on the source side and infer string for T.
// Likewise, we consider a homomorphic mapped type constrainted to the target type parameter as similar to a "naked type variable"
// in such scenarios.
if (!(source.flags & TypeFlags.Union)) {
// Infer between identically matching source and target constituents and remove the matching types.
const [sources, targets] = inferFromMatchingTypes(source.flags & TypeFlags.Intersection ? (source as IntersectionType).types : [source], (target as IntersectionType).types, isTypeIdenticalTo);