Skip to content

Commit 01789d3

Browse files
committed
Clean up inference of type parameters, contravariant types
1 parent cf3af3f commit 01789d3

File tree

1 file changed

+27
-19
lines changed

1 file changed

+27
-19
lines changed

src/compiler/checker.ts

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22556,15 +22556,11 @@ namespace ts {
2255622556
inferFromTypeArguments(getTypeArguments(source as TypeReference), getTypeArguments(target as TypeReference), getVariances((source as TypeReference).target));
2255722557
}
2255822558
else if (source.flags & TypeFlags.Index && target.flags & TypeFlags.Index) {
22559-
contravariant = !contravariant;
22560-
inferFromTypes((source as IndexType).type, (target as IndexType).type);
22561-
contravariant = !contravariant;
22559+
inferFromContravariantTypes((source as IndexType).type, (target as IndexType).type);
2256222560
}
2256322561
else if ((isLiteralType(source) || source.flags & TypeFlags.String) && target.flags & TypeFlags.Index) {
2256422562
const empty = createEmptyObjectTypeFromStringLiteral(source);
22565-
contravariant = !contravariant;
22566-
inferWithPriority(empty, (target as IndexType).type, InferencePriority.LiteralKeyof);
22567-
contravariant = !contravariant;
22563+
inferFromContravariantTypesWithPriority(empty, (target as IndexType).type, InferencePriority.LiteralKeyof);
2256822564
}
2256922565
else if (source.flags & TypeFlags.IndexedAccess && target.flags & TypeFlags.IndexedAccess) {
2257022566
inferFromTypes((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType);
@@ -22577,10 +22573,7 @@ namespace ts {
2257722573
}
2257822574
else if (source.flags & TypeFlags.Substitution) {
2257922575
inferFromTypes((source as SubstitutionType).baseType, target);
22580-
const oldPriority = priority;
22581-
priority |= InferencePriority.SubstituteSource;
22582-
inferFromTypes((source as SubstitutionType).substitute, target); // Make substitute inference at a lower priority
22583-
priority = oldPriority;
22576+
inferWithPriority((source as SubstitutionType).substitute, target, InferencePriority.SubstituteSource); // Make substitute inference at a lower priority
2258422577
}
2258522578
else if (target.flags & TypeFlags.Conditional) {
2258622579
invokeOnce(source, target, inferToConditionalType);
@@ -22631,6 +22624,20 @@ namespace ts {
2263122624
priority = savePriority;
2263222625
}
2263322626

22627+
function inferFromContravariantTypesWithPriority(source: Type, target: Type, newPriority: InferencePriority) {
22628+
const savePriority = priority;
22629+
priority |= newPriority;
22630+
inferFromContravariantTypes(source, target);
22631+
priority = savePriority;
22632+
}
22633+
22634+
function inferToMultipleTypesWithPriority(source: Type, targets: Type[], targetFlags: TypeFlags, newPriority: InferencePriority) {
22635+
const savePriority = priority;
22636+
priority |= newPriority;
22637+
inferToMultipleTypes(source, targets, targetFlags);
22638+
priority = savePriority;
22639+
}
22640+
2263422641
function invokeOnce(source: Type, target: Type, action: (source: Type, target: Type) => void) {
2263522642
const key = source.id + "," + target.id;
2263622643
const status = visited && visited.get(key);
@@ -22694,10 +22701,14 @@ namespace ts {
2269422701
}
2269522702

2269622703
function inferFromContravariantTypes(source: Type, target: Type) {
22704+
contravariant = !contravariant;
22705+
inferFromTypes(source, target);
22706+
contravariant = !contravariant;
22707+
}
22708+
22709+
function inferFromContravariantTypesIfStrictFunctionTypes(source: Type, target: Type) {
2269722710
if (strictFunctionTypes || priority & InferencePriority.AlwaysStrict) {
22698-
contravariant = !contravariant;
22699-
inferFromTypes(source, target);
22700-
contravariant = !contravariant;
22711+
inferFromContravariantTypes(source, target);
2270122712
}
2270222713
else {
2270322714
inferFromTypes(source, target);
@@ -22860,11 +22871,8 @@ namespace ts {
2286022871
inferFromTypes(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target));
2286122872
}
2286222873
else {
22863-
const savePriority = priority;
22864-
priority |= contravariant ? InferencePriority.ContravariantConditional : 0;
2286522874
const targetTypes = [getTrueTypeFromConditionalType(target), getFalseTypeFromConditionalType(target)];
22866-
inferToMultipleTypes(source, targetTypes, target.flags);
22867-
priority = savePriority;
22875+
inferToMultipleTypesWithPriority(source, targetTypes, target.flags, contravariant ? InferencePriority.ContravariantConditional : 0);
2286822876
}
2286922877
}
2287022878

@@ -23059,7 +23067,7 @@ namespace ts {
2305923067
const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown;
2306023068
// Once we descend into a bivariant signature we remain bivariant for all nested inferences
2306123069
bivariant = bivariant || kind === SyntaxKind.MethodDeclaration || kind === SyntaxKind.MethodSignature || kind === SyntaxKind.Constructor;
23062-
applyToParameterTypes(source, target, inferFromContravariantTypes);
23070+
applyToParameterTypes(source, target, inferFromContravariantTypesIfStrictFunctionTypes);
2306323071
bivariant = saveBivariant;
2306423072
applyToReturnTypes(source, target, inferFromTypes);
2306523073
}
@@ -30072,7 +30080,7 @@ namespace ts {
3007230080

3007330081
// Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
3007430082
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, inferenceContext?: InferenceContext, compareTypes?: TypeComparer): Signature {
30075-
const context = createInferenceContext(signature.typeParameters!, signature, InferenceFlags.None, compareTypes);
30083+
const context = createInferenceContext(signature.typeParameters!, signature, inferenceContext?.flags ?? InferenceFlags.None, compareTypes);
3007630084
// We clone the inferenceContext to avoid fixing. For example, when the source signature is <T>(x: T) => T[] and
3007730085
// the contextual signature is (...args: A) => B, we want to infer the element type of A's constraint (say 'any')
3007830086
// for T but leave it possible to later infer '[any]' back to A.

0 commit comments

Comments
 (0)