mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-17 01:49:57 -05:00
Improve logic that chooses co- vs. contra-variant inferences (#57909)
This commit is contained in:
committed by
GitHub
parent
ed81ca6c0a
commit
a71841c77b
@@ -26811,15 +26811,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const inferredContravariantType = inference.contraCandidates ? getContravariantInference(inference) : undefined;
|
||||
if (inferredCovariantType || inferredContravariantType) {
|
||||
// If we have both co- and contra-variant inferences, we prefer the co-variant inference if it is not 'never',
|
||||
// all co-variant inferences are subtypes of it (i.e. it isn't one of a conflicting set of candidates), it is
|
||||
// a subtype of some contra-variant inference, and no other type parameter is constrained to this type parameter
|
||||
// all co-variant inferences are assignable to it (i.e. it isn't one of a conflicting set of candidates), it is
|
||||
// assignable to some contra-variant inference, and no other type parameter is constrained to this type parameter
|
||||
// and has inferences that would conflict. Otherwise, we prefer the contra-variant inference.
|
||||
// Similarly ignore co-variant `any` inference when both are available as almost everything is assignable to it
|
||||
// and it would spoil the overall inference.
|
||||
const preferCovariantType = inferredCovariantType && (!inferredContravariantType ||
|
||||
!(inferredCovariantType.flags & TypeFlags.Never) &&
|
||||
some(inference.contraCandidates, t => isTypeSubtypeOf(inferredCovariantType, t)) &&
|
||||
!(inferredCovariantType.flags & (TypeFlags.Never | TypeFlags.Any)) &&
|
||||
some(inference.contraCandidates, t => isTypeAssignableTo(inferredCovariantType, t)) &&
|
||||
every(context.inferences, other =>
|
||||
other !== inference && getConstraintOfTypeParameter(other.typeParameter) !== inference.typeParameter ||
|
||||
every(other.candidates, t => isTypeSubtypeOf(t, inferredCovariantType))));
|
||||
every(other.candidates, t => isTypeAssignableTo(t, inferredCovariantType))));
|
||||
inferredType = preferCovariantType ? inferredCovariantType : inferredContravariantType;
|
||||
fallbackType = preferCovariantType ? inferredContravariantType : inferredCovariantType;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user