Only make contravariant inferences from pure contravariant positions

This commit is contained in:
Anders Hejlsberg 2018-09-25 18:07:51 -07:00
parent e36957aba1
commit 5e55118076

View file

@ -1,3 +1,6 @@
/* @internal */
namespace ts {
const ambientModuleSymbolRegex = /^".+"$/;
@ -13460,6 +13463,7 @@ namespace ts {
let symbolStack: Symbol[];
let visited: Map<boolean>;
let contravariant = false;
let bivariant = false;
let propagationType: Type;
let allowComplexConstraintInference = true;
inferFromTypes(originalSource, originalTarget);
@ -13546,7 +13550,9 @@ namespace ts {
}
if (priority === inference.priority) {
const candidate = propagationType || source;
if (contravariant) {
// We make contravariant inferences only if we are in a pure contravariant position,
// i.e. only if we have not descended into a bivariant position.
if (contravariant && !bivariant) {
inference.contraCandidates = append(inference.contraCandidates, candidate);
}
else {
@ -13798,7 +13804,12 @@ namespace ts {
function inferFromSignature(source: Signature, target: Signature, skipParameters: boolean) {
if (!skipParameters) {
const saveBivariant = bivariant;
const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown;
// Once we descend into a bivariant signature we remain bivariant for all nested inferences
bivariant = bivariant || kind === SyntaxKind.MethodDeclaration || kind === SyntaxKind.MethodSignature || kind === SyntaxKind.Constructor;
forEachMatchingParameterType(source, target, inferFromContravariantTypes);
bivariant = saveBivariant;
}
const sourceTypePredicate = getTypePredicateOfSignature(source);
const targetTypePredicate = getTypePredicateOfSignature(target);