mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-22 02:35:48 -05:00
Merge pull request #31680 from microsoft/fixGenericReturnTypeInference
Fix generic return type inference
This commit is contained in:
@@ -14933,13 +14933,6 @@ namespace ts {
|
||||
return context && createInferenceContextWorker(map(context.inferences, cloneInferenceInfo), context.signature, context.flags | extraFlags, context.compareTypes);
|
||||
}
|
||||
|
||||
function cloneInferredPartOfContext(context: InferenceContext): InferenceContext | undefined {
|
||||
const inferences = filter(context.inferences, hasInferenceCandidates);
|
||||
return inferences.length ?
|
||||
createInferenceContextWorker(map(inferences, cloneInferenceInfo), context.signature, context.flags, context.compareTypes) :
|
||||
undefined;
|
||||
}
|
||||
|
||||
function createInferenceContextWorker(inferences: InferenceInfo[], signature: Signature | undefined, flags: InferenceFlags, compareTypes: TypeComparer): InferenceContext {
|
||||
const context: InferenceContext = {
|
||||
inferences,
|
||||
@@ -20912,7 +20905,8 @@ namespace ts {
|
||||
// We clone the inference context to avoid disturbing a resolution in progress for an
|
||||
// outer call expression. Effectively we just want a snapshot of whatever has been
|
||||
// inferred for any outer call expression so far.
|
||||
const outerMapper = getMapperFromContext(cloneInferenceContext(getInferenceContext(node), InferenceFlags.NoDefault));
|
||||
const outerContext = getInferenceContext(node);
|
||||
const outerMapper = getMapperFromContext(cloneInferenceContext(outerContext, InferenceFlags.NoDefault));
|
||||
const instantiatedType = instantiateType(contextualType, outerMapper);
|
||||
// If the contextual type is a generic function type with a single call signature, we
|
||||
// instantiate the type with its own type parameters and type arguments. This ensures that
|
||||
@@ -20929,8 +20923,13 @@ namespace ts {
|
||||
// Inferences made from return types have lower priority than all other inferences.
|
||||
inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, InferencePriority.ReturnType);
|
||||
// Create a type mapper for instantiating generic contextual types using the inferences made
|
||||
// from the return type.
|
||||
context.returnMapper = getMapperFromContext(cloneInferredPartOfContext(context));
|
||||
// from the return type. We need a separate inference pass here because (a) instantiation of
|
||||
// the source type uses the outer context's return mapper (which excludes inferences made from
|
||||
// outer arguments), and (b) we don't want any further inferences going into this context.
|
||||
const returnContext = createInferenceContext(signature.typeParameters!, signature, context.flags);
|
||||
const returnSourceType = instantiateType(contextualType, outerContext && outerContext.returnMapper);
|
||||
inferTypes(returnContext.inferences, returnSourceType, inferenceTargetType);
|
||||
context.returnMapper = some(returnContext.inferences, hasInferenceCandidates) ? getMapperFromContext(returnContext) : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user