Skip to content

Commit 9e613b9

Browse files
committed
Preserve type parameters in generic contextual pure function types
1 parent dbf0362 commit 9e613b9

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

src/compiler/checker.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14959,11 +14959,21 @@ namespace ts {
1495914959
// We clone the contextual mapper to avoid disturbing a resolution in progress for an
1496014960
// outer call expression. Effectively we just want a snapshot of whatever has been
1496114961
// inferred for any outer call expression so far.
14962-
const mapper = cloneTypeMapper(getContextualMapper(node));
14963-
const instantiatedType = instantiateType(contextualType, mapper);
14964-
const returnType = getReturnTypeOfSignature(signature);
14965-
// Inferences made from return types have lower priority than all other inferences.
14966-
inferTypes(context.inferences, instantiatedType, returnType, InferencePriority.ReturnType);
14962+
const instantiatedType = instantiateType(contextualType, cloneTypeMapper(getContextualMapper(node)));
14963+
// If the contextual type is a generic pure function type, we instantiate the type with
14964+
// its own type parameters and type arguments. This ensures that the type parameters are
14965+
// not erased to type any during type inference such that they can be inferred as actual
14966+
// types from the contextual type. For example:
14967+
// declare function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[];
14968+
// const boxElements: <A>(a: A[]) => { value: A }[] = arrayMap(value => ({ value }));
14969+
// Above, the type of the 'value' parameter is inferred to be 'A'.
14970+
const contextualSignature = getSingleCallSignature(instantiatedType);
14971+
const inferenceSourceType = contextualSignature && contextualSignature.typeParameters ?
14972+
getOrCreateTypeFromSignature(getSignatureInstantiation(contextualSignature, contextualSignature.typeParameters)) :
14973+
instantiatedType;
14974+
const inferenceTargetType = getReturnTypeOfSignature(signature);
14975+
// Inferences made from return types have lower priority than all other inferences.
14976+
inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, InferencePriority.ReturnType);
1496714977
}
1496814978
}
1496914979

0 commit comments

Comments
 (0)