@@ -25318,19 +25318,25 @@ namespace ts {
25318
25318
if (!assumeTrue) {
25319
25319
return filterType(type, t => !isRelated(t, candidate));
25320
25320
}
25321
+ if (type.flags & TypeFlags.AnyOrUnknown) {
25322
+ return candidate;
25323
+ }
25321
25324
// We first attempt to filter the current type, narrowing constituents as appropriate and removing
25322
25325
// constituents that are unrelated to the candidate.
25323
- const narrowedType = type.flags & TypeFlags.AnyOrUnknown ? candidate :
25324
- mapType(candidate, c => {
25325
- // For each constituent t in the current type, if t and and c are directly related, pick the most
25326
- // specific of the two.
25327
- const directlyRelated = mapType(type, t => isRelated(t, c) ? t : isRelated(c, t) ? c : neverType);
25328
- // If no constituents are directly related, create intersections for any generic constituents that
25329
- // are related by constraint.
25330
- return directlyRelated.flags & TypeFlags.Never ?
25331
- mapType(type, t => maybeTypeOfKind(t, TypeFlags.Instantiable) && isRelated(c, getBaseConstraintOfType(t) || unknownType) ? getIntersectionType([t, c]) : neverType) :
25332
- directlyRelated;
25333
- });
25326
+ const keyPropertyName = type.flags & TypeFlags.Union ? getKeyPropertyName(type as UnionType) : undefined;
25327
+ const narrowedType = mapType(candidate, c => {
25328
+ // If a discriminant property is available, use that to reduce the type.
25329
+ const discriminant = keyPropertyName && getTypeOfPropertyOfType(c, keyPropertyName);
25330
+ const matching = discriminant && getConstituentTypeForKeyType(type as UnionType, discriminant);
25331
+ // For each constituent t in the current type, if t and and c are directly related, pick the most
25332
+ // specific of the two.
25333
+ const directlyRelated = mapType(matching || type, t => isRelated(t, c) ? t : isRelated(c, t) ? c : neverType);
25334
+ // If no constituents are directly related, create intersections for any generic constituents that
25335
+ // are related by constraint.
25336
+ return directlyRelated.flags & TypeFlags.Never ?
25337
+ mapType(type, t => maybeTypeOfKind(t, TypeFlags.Instantiable) && isRelated(c, getBaseConstraintOfType(t) || unknownType) ? getIntersectionType([t, c]) : neverType) :
25338
+ directlyRelated;
25339
+ });
25334
25340
// If filtering produced a non-empty type, return that. Otherwise, pick the most specific of the two
25335
25341
// based on assignability, or as a last resort produce an intersection.
25336
25342
return !(narrowedType.flags & TypeFlags.Never) ? narrowedType :
0 commit comments