@@ -26519,7 +26519,7 @@ namespace ts {
2651926519 if (result) {
2652026520 return result;
2652126521 }
26522- if (!(contextFlags! & ContextFlags.SkipBindingPatterns) && isBindingPattern(declaration.name)) { // This is less a contextual type and more an implied shape - in some cases, this may be undesirable
26522+ if (!(contextFlags! & ContextFlags.SkipBindingPatterns) && isBindingPattern(declaration.name) && declaration.name.elements.length > 0) {
2652326523 return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false);
2652426524 }
2652526525 }
@@ -27053,22 +27053,20 @@ namespace ts {
2705327053 const inferenceContext = getInferenceContext(node);
2705427054 // If no inferences have been made, nothing is gained from instantiating as type parameters
2705527055 // would just be replaced with their defaults similar to the apparent type.
27056- if (inferenceContext && some(inferenceContext.inferences, hasInferenceCandidates)) {
27056+ if (inferenceContext && contextFlags! & ContextFlags.Signature && some(inferenceContext.inferences, hasInferenceCandidates)) {
2705727057 // For contextual signatures we incorporate all inferences made so far, e.g. from return
2705827058 // types as well as arguments to the left in a function call.
27059- if (contextFlags && contextFlags & ContextFlags.Signature) {
27060- return instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper);
27061- }
27059+ return instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper);
27060+ }
27061+ if (inferenceContext?.returnMapper) {
2706227062 // For other purposes (e.g. determining whether to produce literal types) we only
2706327063 // incorporate inferences made from the return type in a function call. We remove
2706427064 // the 'boolean' type from the contextual type such that contextually typed boolean
2706527065 // literals actually end up widening to 'boolean' (see #48363).
27066- if (inferenceContext.returnMapper) {
27067- const type = instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper);
27068- return type.flags & TypeFlags.Union && containsType((type as UnionType).types, regularFalseType) && containsType((type as UnionType).types, regularTrueType) ?
27069- filterType(type, t => t !== regularFalseType && t !== regularTrueType) :
27070- type;
27071- }
27066+ const type = instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper);
27067+ return type.flags & TypeFlags.Union && containsType((type as UnionType).types, regularFalseType) && containsType((type as UnionType).types, regularTrueType) ?
27068+ filterType(type, t => t !== regularFalseType && t !== regularTrueType) :
27069+ type;
2707227070 }
2707327071 }
2707427072 return contextualType;
@@ -29904,29 +29902,43 @@ namespace ts {
2990429902 // 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the
2990529903 // return type of 'wrap'.
2990629904 if (node.kind !== SyntaxKind.Decorator) {
29907- const contextualType = getContextualType(node, every(signature.typeParameters, p => !!getDefaultFromTypeParameter(p)) ? ContextFlags.SkipBindingPatterns : ContextFlags.None);
29905+ const skipBindingPatterns = every(signature.typeParameters, p => !!getDefaultFromTypeParameter(p));
29906+ const contextualType = getContextualType(node, skipBindingPatterns ? ContextFlags.SkipBindingPatterns : ContextFlags.None);
2990829907 if (contextualType) {
2990929908 const inferenceTargetType = getReturnTypeOfSignature(signature);
2991029909 if (couldContainTypeVariables(inferenceTargetType)) {
29911- // We clone the inference context to avoid disturbing a resolution in progress for an
29912- // outer call expression. Effectively we just want a snapshot of whatever has been
29913- // inferred for any outer call expression so far.
2991429910 const outerContext = getInferenceContext(node);
29915- const outerMapper = getMapperFromContext(cloneInferenceContext(outerContext, InferenceFlags.NoDefault));
29916- const instantiatedType = instantiateType(contextualType, outerMapper);
29917- // If the contextual type is a generic function type with a single call signature, we
29918- // instantiate the type with its own type parameters and type arguments. This ensures that
29919- // the type parameters are not erased to type any during type inference such that they can
29920- // be inferred as actual types from the contextual type. For example:
29921- // declare function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[];
29922- // const boxElements: <A>(a: A[]) => { value: A }[] = arrayMap(value => ({ value }));
29923- // Above, the type of the 'value' parameter is inferred to be 'A'.
29924- const contextualSignature = getSingleCallSignature(instantiatedType);
29925- const inferenceSourceType = contextualSignature && contextualSignature.typeParameters ?
29926- getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters)) :
29927- instantiatedType;
29928- // Inferences made from return types have lower priority than all other inferences.
29929- inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, InferencePriority.ReturnType);
29911+ const isFromBindingPattern = !skipBindingPatterns && getContextualType(node, ContextFlags.SkipBindingPatterns) !== contextualType;
29912+ // A return type inference from a binding pattern can be used in instantiating the contextual
29913+ // type of an argument later in inference, but cannot stand on its own as the final return type.
29914+ // It is incorporated into `context.returnMapper` which is used in `instantiateContextualType`,
29915+ // but doesn't need to go into `context.inferences`. This allows a an array binding pattern to
29916+ // produce a tuple for `T` in
29917+ // declare function f<T>(cb: () => T): T;
29918+ // const [e1, e2, e3] = f(() => [1, "hi", true]);
29919+ // but does not produce any inference for `T` in
29920+ // declare function f<T>(): T;
29921+ // const [e1, e2, e3] = f();
29922+ if (!isFromBindingPattern) {
29923+ // We clone the inference context to avoid disturbing a resolution in progress for an
29924+ // outer call expression. Effectively we just want a snapshot of whatever has been
29925+ // inferred for any outer call expression so far.
29926+ const outerMapper = getMapperFromContext(cloneInferenceContext(outerContext, InferenceFlags.NoDefault));
29927+ const instantiatedType = instantiateType(contextualType, outerMapper);
29928+ // If the contextual type is a generic function type with a single call signature, we
29929+ // instantiate the type with its own type parameters and type arguments. This ensures that
29930+ // the type parameters are not erased to type any during type inference such that they can
29931+ // be inferred as actual types from the contextual type. For example:
29932+ // declare function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[];
29933+ // const boxElements: <A>(a: A[]) => { value: A }[] = arrayMap(value => ({ value }));
29934+ // Above, the type of the 'value' parameter is inferred to be 'A'.
29935+ const contextualSignature = getSingleCallSignature(instantiatedType);
29936+ const inferenceSourceType = contextualSignature && contextualSignature.typeParameters ?
29937+ getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters)) :
29938+ instantiatedType;
29939+ // Inferences made from return types have lower priority than all other inferences.
29940+ inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, InferencePriority.ReturnType);
29941+ }
2993029942 // Create a type mapper for instantiating generic contextual types using the inferences made
2993129943 // from the return type. We need a separate inference pass here because (a) instantiation of
2993229944 // the source type uses the outer context's return mapper (which excludes inferences made from
0 commit comments