@@ -22947,46 +22947,39 @@ namespace ts {
22947
22947
if (!inference.inferredType) {
22948
22948
let inferredType: Type | undefined;
22949
22949
const signature = context.signature;
22950
- if (!(inference.priority! & InferencePriority.BindingPattern)) {
22951
- // Binding pattern inferences provide a contextual type for other inferences,
22952
- // but cannot stand alone - they are expected to be overwritten by another
22953
- // inference with higher priority before fixing. This prevents highly suspicious
22954
- // patterns like `function f<T>(): T; const { foo } = f()` from inferring T as
22955
- // `{ foo: any }`.
22956
- if (signature) {
22957
- const inferredCovariantType = inference.candidates ? getCovariantInference(inference, signature) : undefined;
22958
- if (inference.contraCandidates) {
22959
- // If we have both co- and contra-variant inferences, we prefer the contra-variant inference
22960
- // unless the co-variant inference is a subtype of some contra-variant inference and not 'never'.
22961
- inferredType = inferredCovariantType && !(inferredCovariantType.flags & TypeFlags.Never) &&
22962
- some(inference.contraCandidates, t => isTypeSubtypeOf(inferredCovariantType, t)) ?
22963
- inferredCovariantType : getContravariantInference(inference);
22964
- }
22965
- else if (inferredCovariantType) {
22966
- inferredType = inferredCovariantType;
22967
- }
22968
- else if (context.flags & InferenceFlags.NoDefault) {
22969
- // We use silentNeverType as the wildcard that signals no inferences.
22970
- inferredType = silentNeverType;
22971
- }
22972
- else {
22973
- // Infer either the default or the empty object type when no inferences were
22974
- // made. It is important to remember that in this case, inference still
22975
- // succeeds, meaning there is no error for not having inference candidates. An
22976
- // inference error only occurs when there are *conflicting* candidates, i.e.
22977
- // candidates with no common supertype.
22978
- const defaultType = getDefaultFromTypeParameter(inference.typeParameter);
22979
- if (defaultType) {
22980
- // Instantiate the default type. Any forward reference to a type
22981
- // parameter should be instantiated to the empty object type.
22982
- inferredType = instantiateType(defaultType, mergeTypeMappers(createBackreferenceMapper(context, index), context.nonFixingMapper));
22983
- }
22984
- }
22950
+ if (signature) {
22951
+ const inferredCovariantType = inference.candidates ? getCovariantInference(inference, signature) : undefined;
22952
+ if (inference.contraCandidates) {
22953
+ // If we have both co- and contra-variant inferences, we prefer the contra-variant inference
22954
+ // unless the co-variant inference is a subtype of some contra-variant inference and not 'never'.
22955
+ inferredType = inferredCovariantType && !(inferredCovariantType.flags & TypeFlags.Never) &&
22956
+ some(inference.contraCandidates, t => isTypeSubtypeOf(inferredCovariantType, t)) ?
22957
+ inferredCovariantType : getContravariantInference(inference);
22958
+ }
22959
+ else if (inferredCovariantType) {
22960
+ inferredType = inferredCovariantType;
22961
+ }
22962
+ else if (context.flags & InferenceFlags.NoDefault) {
22963
+ // We use silentNeverType as the wildcard that signals no inferences.
22964
+ inferredType = silentNeverType;
22985
22965
}
22986
22966
else {
22987
- inferredType = getTypeFromInference(inference);
22967
+ // Infer either the default or the empty object type when no inferences were
22968
+ // made. It is important to remember that in this case, inference still
22969
+ // succeeds, meaning there is no error for not having inference candidates. An
22970
+ // inference error only occurs when there are *conflicting* candidates, i.e.
22971
+ // candidates with no common supertype.
22972
+ const defaultType = getDefaultFromTypeParameter(inference.typeParameter);
22973
+ if (defaultType) {
22974
+ // Instantiate the default type. Any forward reference to a type
22975
+ // parameter should be instantiated to the empty object type.
22976
+ inferredType = instantiateType(defaultType, mergeTypeMappers(createBackreferenceMapper(context, index), context.nonFixingMapper));
22977
+ }
22988
22978
}
22989
22979
}
22980
+ else {
22981
+ inferredType = getTypeFromInference(inference);
22982
+ }
22990
22983
22991
22984
inference.inferredType = inferredType || getDefaultTypeArgumentType(!!(context.flags & InferenceFlags.AnyDefault));
22992
22985
@@ -27062,22 +27055,22 @@ namespace ts {
27062
27055
const inferenceContext = getInferenceContext(node);
27063
27056
// If no inferences have been made, nothing is gained from instantiating as type parameters
27064
27057
// would just be replaced with their defaults similar to the apparent type.
27065
- if (inferenceContext && some(inferenceContext.inferences, hasInferenceCandidates)) {
27058
+ if (inferenceContext && contextFlags! & ContextFlags.Signature && (inferenceContext.returnMapper || some(inferenceContext.inferences, hasInferenceCandidates) )) {
27066
27059
// For contextual signatures we incorporate all inferences made so far, e.g. from return
27067
27060
// types as well as arguments to the left in a function call.
27068
- if (contextFlags && contextFlags & ContextFlags.Signature) {
27069
- return instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper);
27070
- }
27061
+ return instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper
27062
+ ? combineTypeMappers(inferenceContext.nonFixingMapper, inferenceContext.returnMapper)
27063
+ : inferenceContext.nonFixingMapper);
27064
+ }
27065
+ if (inferenceContext?.returnMapper) {
27071
27066
// For other purposes (e.g. determining whether to produce literal types) we only
27072
27067
// incorporate inferences made from the return type in a function call. We remove
27073
27068
// the 'boolean' type from the contextual type such that contextually typed boolean
27074
27069
// literals actually end up widening to 'boolean' (see #48363).
27075
- if (inferenceContext.returnMapper) {
27076
- const type = instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper);
27077
- return type.flags & TypeFlags.Union && containsType((type as UnionType).types, regularFalseType) && containsType((type as UnionType).types, regularTrueType) ?
27078
- filterType(type, t => t !== regularFalseType && t !== regularTrueType) :
27079
- type;
27080
- }
27070
+ const type = instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper);
27071
+ return type.flags & TypeFlags.Union && containsType((type as UnionType).types, regularFalseType) && containsType((type as UnionType).types, regularTrueType) ?
27072
+ filterType(type, t => t !== regularFalseType && t !== regularTrueType) :
27073
+ type;
27081
27074
}
27082
27075
}
27083
27076
return contextualType;
@@ -29918,27 +29911,38 @@ namespace ts {
29918
29911
if (contextualType) {
29919
29912
const inferenceTargetType = getReturnTypeOfSignature(signature);
29920
29913
if (couldContainTypeVariables(inferenceTargetType)) {
29921
- // We clone the inference context to avoid disturbing a resolution in progress for an
29922
- // outer call expression. Effectively we just want a snapshot of whatever has been
29923
- // inferred for any outer call expression so far.
29924
29914
const outerContext = getInferenceContext(node);
29925
- const outerMapper = getMapperFromContext(cloneInferenceContext(outerContext, InferenceFlags.NoDefault));
29926
- const instantiatedType = instantiateType(contextualType, outerMapper);
29927
- // If the contextual type is a generic function type with a single call signature, we
29928
- // instantiate the type with its own type parameters and type arguments. This ensures that
29929
- // the type parameters are not erased to type any during type inference such that they can
29930
- // be inferred as actual types from the contextual type. For example:
29931
- // declare function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[];
29932
- // const boxElements: <A>(a: A[]) => { value: A }[] = arrayMap(value => ({ value }));
29933
- // Above, the type of the 'value' parameter is inferred to be 'A'.
29934
- const contextualSignature = getSingleCallSignature(instantiatedType);
29935
- const inferenceSourceType = contextualSignature && contextualSignature.typeParameters ?
29936
- getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters)) :
29937
- instantiatedType;
29938
- // Inferences made from return types have lower priority than all other inferences.
29939
29915
const isFromBindingPattern = !skipBindingPatterns && getContextualType(node, ContextFlags.SkipBindingPatterns) !== contextualType;
29940
- const priority = InferencePriority.ReturnType | (isFromBindingPattern ? InferencePriority.BindingPattern : 0);
29941
- inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, priority);
29916
+ // A return type inference from a binding pattern can be used in instantiating the contextual
29917
+ // type of an argument later in inference, but cannot stand on its own as the final return type.
29918
+ // It is incorporated into `context.returnMapper` which is used in `instantiateContextualType`,
29919
+ // but doesn't need to go into `context.inferences`. This allows a an array binding pattern to
29920
+ // produce a tuple for `T` in
29921
+ // declare function f<T>(cb: () => T): T;
29922
+ // const [e1, e2, e3] = f(() => [1, "hi", true]);
29923
+ // but does not produce any inference for `T` in
29924
+ // declare function f<T>(): T;
29925
+ // const [e1, e2, e3] = f();
29926
+ if (!isFromBindingPattern) {
29927
+ // We clone the inference context to avoid disturbing a resolution in progress for an
29928
+ // outer call expression. Effectively we just want a snapshot of whatever has been
29929
+ // inferred for any outer call expression so far.
29930
+ const outerMapper = getMapperFromContext(cloneInferenceContext(outerContext, InferenceFlags.NoDefault));
29931
+ const instantiatedType = instantiateType(contextualType, outerMapper);
29932
+ // If the contextual type is a generic function type with a single call signature, we
29933
+ // instantiate the type with its own type parameters and type arguments. This ensures that
29934
+ // the type parameters are not erased to type any during type inference such that they can
29935
+ // be inferred as actual types from the contextual type. For example:
29936
+ // declare function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[];
29937
+ // const boxElements: <A>(a: A[]) => { value: A }[] = arrayMap(value => ({ value }));
29938
+ // Above, the type of the 'value' parameter is inferred to be 'A'.
29939
+ const contextualSignature = getSingleCallSignature(instantiatedType);
29940
+ const inferenceSourceType = contextualSignature && contextualSignature.typeParameters ?
29941
+ getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters)) :
29942
+ instantiatedType;
29943
+ // Inferences made from return types have lower priority than all other inferences.
29944
+ inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, InferencePriority.ReturnType);
29945
+ }
29942
29946
// Create a type mapper for instantiating generic contextual types using the inferences made
29943
29947
// from the return type. We need a separate inference pass here because (a) instantiation of
29944
29948
// the source type uses the outer context's return mapper (which excludes inferences made from
0 commit comments