Skip to content

Commit

Permalink
Refactor 'getNarrowableTypeForReference'.
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielRosenwasser authored Apr 27, 2022
1 parent 063220a commit 1e2eb03
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25338,13 +25338,24 @@ namespace ts {
// control flow analysis an opportunity to narrow it further. For example, for a reference of a type
// parameter type 'T extends string | undefined' with a contextual type 'string', we substitute
// 'string | undefined' to give control flow analysis the opportunity to narrow to type 'string'.
if (checkMode && checkMode & CheckMode.Inferential) {
return type;
}

let contextualType: Type | undefined;
const substituteConstraints = !(checkMode && checkMode & CheckMode.Inferential) &&
(isConstraintPosition(type, reference) || (contextualType = tryGetContextualTypeWithNoGenericTypes(reference, checkMode))) &&
(
someType(type, isGenericTypeWithUnionConstraint) ||
((type.flags & TypeFlags.Instantiable) && contextualType && isEmptyObjectType(contextualType))
);
// If we aren't in a constraint position, or we can't find a contextual type, or the contextual type indicates
// that the type in question may be a direct inference source, then don't do anything special.
if (!isConstraintPosition(type, reference) && !(contextualType = tryGetContextualTypeWithNoGenericTypes(reference, checkMode))) {
return type;
}

const substituteConstraints =
// When we have a type parameter constrained to a union type, we can typically narrow to get better results.
someType(type, isGenericTypeWithUnionConstraint) ||
// When the contextual type is 'unknown', we may need to narrow for compatibility with non-null targets.
// This allows some parity with a constraint of '{} | null | undefined'.
(type.flags & TypeFlags.Instantiable) && contextualType && isEmptyObjectType(contextualType);

return substituteConstraints ? mapType(type, t => t.flags & TypeFlags.Instantiable ? getBaseConstraintOfType(t) || unknownType : t) : type;
}

Expand Down

0 comments on commit 1e2eb03

Please sign in to comment.