Skip to content

Commit 6d88251

Browse files
committed
Minor change to heuristic for deferring generic calls
1 parent 6c790c0 commit 6d88251

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

src/compiler/checker.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20900,10 +20900,19 @@ namespace ts {
2090020900
}
2090120901
return resolveErrorCall(node);
2090220902
}
20903-
// If we are skipping generic functions (i.e. this call is an argument to another call for which context
20904-
// sensitive arguments are being deferred) and every call signature is generic and returns a function type,
20905-
// we return resolvingSignature here. This result will be propagated out and turned into anyFunctionType.
20906-
if (checkMode & CheckMode.SkipGenericFunctions && callSignatures.every(isGenericFunctionReturningFunction)) {
20903+
// When a call to a generic function is an argument to an outer call to a generic function for which
20904+
// inference is in process, we have a choice to make. If the inner call relies on inferences made from
20905+
// its contextual type to its return type, deferring the inner call processing allows the best possible
20906+
// contextual type to accumulate. But if the outer call relies on inferences made from the return type of
20907+
// the inner call, the inner call should be processed early. There's no sure way to know which choice is
20908+
// right (only a full unification algorithm can determine that), so we resort to the following heuristic:
20909+
// If no type arguments are specified in the inner call and at least one call signature is generic and
20910+
// returns a function type, we choose to defer processing. This narrowly permits function composition
20911+
// operators to flow inferences through return types, but otherwise processes calls right away. We
20912+
// use the resolvingSignature singleton to indicate that we deferred processing. This result will be
20913+
// propagated out and eventually turned into silentNeverType (a type that is assignable to anything and
20914+
// from which we never make inferences).
20915+
if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
2090720916
skippedGenericFunction(node, checkMode);
2090820917
return resolvingSignature;
2090920918
}
@@ -21385,7 +21394,7 @@ namespace ts {
2138521394
if (signature === resolvingSignature) {
2138621395
// CheckMode.SkipGenericFunctions is enabled and this is a call to a generic function that
2138721396
// returns a function type. We defer checking and return anyFunctionType.
21388-
return anyFunctionType;
21397+
return silentNeverType;
2138921398
}
2139021399

2139121400
if (node.expression.kind === SyntaxKind.SuperKeyword) {

0 commit comments

Comments
 (0)