Improve contextual typing by generic rest parameter
This commit is contained in:
parent
b2b360a64f
commit
451f65332c
1 changed files with 14 additions and 3 deletions
|
@ -10669,9 +10669,9 @@ namespace ts {
|
|||
return !!(<InferenceContext>mapper).typeParameters;
|
||||
}
|
||||
|
||||
function cloneTypeMapper(mapper: TypeMapper): TypeMapper {
|
||||
function cloneTypeMapper(mapper: TypeMapper, extraFlags: InferenceFlags = 0): TypeMapper {
|
||||
return mapper && isInferenceContext(mapper) ?
|
||||
createInferenceContext(mapper.typeParameters, mapper.signature, mapper.flags | InferenceFlags.NoDefault, mapper.compareTypes, mapper.inferences) :
|
||||
createInferenceContext(mapper.typeParameters, mapper.signature, mapper.flags | extraFlags, mapper.compareTypes, mapper.inferences) :
|
||||
mapper;
|
||||
}
|
||||
|
||||
|
@ -19984,7 +19984,7 @@ namespace ts {
|
|||
// We clone the contextual mapper 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 instantiatedType = instantiateType(contextualType, cloneTypeMapper(getContextualMapper(node)));
|
||||
const instantiatedType = instantiateType(contextualType, cloneTypeMapper(getContextualMapper(node), InferenceFlags.NoDefault));
|
||||
// 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
|
||||
// the type parameters are not erased to type any during type inference such that they can
|
||||
|
@ -21652,6 +21652,17 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
}
|
||||
const restType = getEffectiveRestType(context);
|
||||
if (restType && restType.flags & TypeFlags.TypeParameter) {
|
||||
// The contextual signature has a generic rest parameter. We first instantiate the contextual
|
||||
// signature (without fixing type parameters) and assign types to contextually typed parameters.
|
||||
const instantiatedContext = instantiateSignature(context, cloneTypeMapper(mapper));
|
||||
assignContextualParameterTypes(signature, instantiatedContext);
|
||||
// We then infer from a tuple type representing the parameters that correspond to the contextual
|
||||
// rest parameter.
|
||||
const restPos = getParameterCount(context) - 1;
|
||||
inferTypes((<InferenceContext>mapper).inferences, getRestTypeAtPosition(signature, restPos), restType);
|
||||
}
|
||||
}
|
||||
|
||||
function assignContextualParameterTypes(signature: Signature, context: Signature) {
|
||||
|
|
Loading…
Reference in a new issue