@@ -176,15 +176,16 @@ namespace ts {
176176 }
177177
178178 const enum CheckMode {
179- Normal = 0, // Normal type checking
180- Contextual = 1 << 0, // Explicitly assigned contextual type, therefore not cacheable
181- Inferential = 1 << 1, // Inferential typing
182- SkipContextSensitive = 1 << 2, // Skip context sensitive function expressions
183- SkipGenericFunctions = 1 << 3, // Skip single signature generic functions
184- IsForSignatureHelp = 1 << 4, // Call resolution for purposes of signature help
185- RestBindingElement = 1 << 5, // Checking a type that is going to be used to determine the type of a rest binding element
186- // e.g. in `const { a, ...rest } = foo`, when checking the type of `foo` to determine the type of `rest`,
187- // we need to preserve generic types instead of substituting them for constraints
179+ Normal = 0, // Normal type checking
180+ Contextual = 1 << 0, // Explicitly assigned contextual type, therefore not cacheable
181+ Inferential = 1 << 1, // Inferential typing
182+ SkipContextSensitive = 1 << 2, // Skip context sensitive function expressions
183+ SkipGenericFunctions = 1 << 3, // Skip single signature generic functions
184+ IsForSignatureHelp = 1 << 4, // Call resolution for purposes of signature help
185+ IsForStringLiteralArgumentCompletions = 1 << 5, // Do not infer from the argument currently being typed
186+ RestBindingElement = 1 << 6, // Checking a type that is going to be used to determine the type of a rest binding element
187+ // e.g. in `const { a, ...rest } = foo`, when checking the type of `foo` to determine the type of `rest`,
188+ // we need to preserve generic types instead of substituting them for constraints
188189 }
189190
190191 const enum SignatureCheckMode {
@@ -540,26 +541,10 @@ namespace ts {
540541 if (!node) {
541542 return undefined;
542543 }
543- const containingCall = findAncestor(node, isCallLikeExpression);
544- const containingCallResolvedSignature = containingCall && getNodeLinks(containingCall).resolvedSignature;
545- if (contextFlags! & ContextFlags.Completions && containingCall) {
546- let toMarkSkip = node as Node;
547- do {
548- getNodeLinks(toMarkSkip).skipDirectInference = true;
549- toMarkSkip = toMarkSkip.parent;
550- } while (toMarkSkip && toMarkSkip !== containingCall);
551- getNodeLinks(containingCall).resolvedSignature = undefined;
552- }
553- const result = getContextualType(node, contextFlags);
554- if (contextFlags! & ContextFlags.Completions && containingCall) {
555- let toMarkSkip = node as Node;
556- do {
557- getNodeLinks(toMarkSkip).skipDirectInference = undefined;
558- toMarkSkip = toMarkSkip.parent;
559- } while (toMarkSkip && toMarkSkip !== containingCall);
560- getNodeLinks(containingCall).resolvedSignature = containingCallResolvedSignature;
544+ if (contextFlags! & ContextFlags.Completions) {
545+ return runWithInferenceBlockedFromSourceNode(node, () => getContextualType(node, contextFlags));
561546 }
562- return result ;
547+ return getContextualType(node, contextFlags) ;
563548 },
564549 getContextualTypeForObjectLiteralElement: nodeIn => {
565550 const node = getParseTreeNode(nodeIn, isObjectLiteralElementLike);
@@ -578,6 +563,8 @@ namespace ts {
578563 getFullyQualifiedName,
579564 getResolvedSignature: (node, candidatesOutArray, argumentCount) =>
580565 getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.Normal),
566+ getResolvedSignatureForStringLiteralCompletions: (call, editingArgument, candidatesOutArray) =>
567+ getResolvedSignatureWorker(call, candidatesOutArray, /*argumentCount*/ undefined, CheckMode.IsForStringLiteralArgumentCompletions, editingArgument),
581568 getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, argumentCount) =>
582569 getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.IsForSignatureHelp),
583570 getExpandedParameters,
@@ -747,10 +734,36 @@ namespace ts {
747734 getMemberOverrideModifierStatus,
748735 };
749736
750- function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, checkMode: CheckMode): Signature | undefined {
737+ function runWithInferenceBlockedFromSourceNode<T>(node: Node | undefined, fn: () => T): T {
738+ const containingCall = findAncestor(node, isCallLikeExpression);
739+ const containingCallResolvedSignature = containingCall && getNodeLinks(containingCall).resolvedSignature;
740+ if (containingCall) {
741+ let toMarkSkip = node!;
742+ do {
743+ getNodeLinks(toMarkSkip).skipDirectInference = true;
744+ toMarkSkip = toMarkSkip.parent;
745+ } while (toMarkSkip && toMarkSkip !== containingCall);
746+ getNodeLinks(containingCall).resolvedSignature = undefined;
747+ }
748+ const result = fn();
749+ if (containingCall) {
750+ let toMarkSkip = node!;
751+ do {
752+ getNodeLinks(toMarkSkip).skipDirectInference = undefined;
753+ toMarkSkip = toMarkSkip.parent;
754+ } while (toMarkSkip && toMarkSkip !== containingCall);
755+ getNodeLinks(containingCall).resolvedSignature = containingCallResolvedSignature;
756+ }
757+ return result;
758+ }
759+
760+ function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, checkMode: CheckMode, editingArgument?: Node): Signature | undefined {
751761 const node = getParseTreeNode(nodeIn, isCallLikeExpression);
752762 apparentArgumentCount = argumentCount;
753- const res = node ? getResolvedSignature(node, candidatesOutArray, checkMode) : undefined;
763+ const res =
764+ !node ? undefined :
765+ editingArgument ? runWithInferenceBlockedFromSourceNode(editingArgument, () => getResolvedSignature(node, candidatesOutArray, checkMode)) :
766+ getResolvedSignature(node, candidatesOutArray, checkMode);
754767 apparentArgumentCount = undefined;
755768 return res;
756769 }
@@ -22664,7 +22677,7 @@ namespace ts {
2266422677 const properties = getPropertiesOfObjectType(target);
2266522678 for (const targetProp of properties) {
2266622679 const sourceProp = getPropertyOfType(source, targetProp.escapedName);
22667- if (sourceProp) {
22680+ if (sourceProp && !some(sourceProp.declarations, hasSkipDirectInferenceFlag) ) {
2266822681 inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
2266922682 }
2267022683 }
@@ -29746,7 +29759,7 @@ namespace ts {
2974629759
2974729760 for (let i = 0; i < argCount; i++) {
2974829761 const arg = args[i];
29749- if (arg.kind !== SyntaxKind.OmittedExpression) {
29762+ if (arg.kind !== SyntaxKind.OmittedExpression && !(checkMode & CheckMode.IsForStringLiteralArgumentCompletions && hasSkipDirectInferenceFlag(arg)) ) {
2975029763 const paramType = getTypeAtPosition(signature, i);
2975129764 const argType = checkExpressionWithContextualType(arg, paramType, context, checkMode);
2975229765 inferTypes(context.inferences, argType, paramType);
@@ -30486,7 +30499,7 @@ namespace ts {
3048630499 }
3048730500 }
3048830501
30489- return getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray);
30502+ return getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray, checkMode );
3049030503
3049130504 function addImplementationSuccessElaboration(failed: Signature, diagnostic: Diagnostic) {
3049230505 const oldCandidatesForArgumentError = candidatesForArgumentError;
@@ -30600,14 +30613,15 @@ namespace ts {
3060030613 candidates: Signature[],
3060130614 args: readonly Expression[],
3060230615 hasCandidatesOutArray: boolean,
30616+ checkMode: CheckMode,
3060330617 ): Signature {
3060430618 Debug.assert(candidates.length > 0); // Else should not have called this.
3060530619 checkNodeDeferred(node);
3060630620 // Normally we will combine overloads. Skip this if they have type parameters since that's hard to combine.
3060730621 // Don't do this if there is a `candidatesOutArray`,
3060830622 // because then we want the chosen best candidate to be one of the overloads, not a combination.
3060930623 return hasCandidatesOutArray || candidates.length === 1 || candidates.some(c => !!c.typeParameters)
30610- ? pickLongestCandidateSignature(node, candidates, args)
30624+ ? pickLongestCandidateSignature(node, candidates, args, checkMode )
3061130625 : createUnionOfSignaturesForOverloadFailure(candidates);
3061230626 }
3061330627
@@ -30661,7 +30675,7 @@ namespace ts {
3066130675 return createSymbolWithType(first(sources), type);
3066230676 }
3066330677
30664- function pickLongestCandidateSignature(node: CallLikeExpression, candidates: Signature[], args: readonly Expression[]): Signature {
30678+ function pickLongestCandidateSignature(node: CallLikeExpression, candidates: Signature[], args: readonly Expression[], checkMode: CheckMode ): Signature {
3066530679 // Pick the longest signature. This way we can get a contextual type for cases like:
3066630680 // declare function f(a: { xa: number; xb: number; }, b: number);
3066730681 // f({ |
@@ -30678,7 +30692,7 @@ namespace ts {
3067830692 const typeArgumentNodes: readonly TypeNode[] | undefined = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments : undefined;
3067930693 const instantiated = typeArgumentNodes
3068030694 ? createSignatureInstantiation(candidate, getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, isInJSFile(node)))
30681- : inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args);
30695+ : inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args, checkMode );
3068230696 candidates[bestIndex] = instantiated;
3068330697 return instantiated;
3068430698 }
@@ -30694,9 +30708,9 @@ namespace ts {
3069430708 return typeArguments;
3069530709 }
3069630710
30697- function inferSignatureInstantiationForOverloadFailure(node: CallLikeExpression, typeParameters: readonly TypeParameter[], candidate: Signature, args: readonly Expression[]): Signature {
30711+ function inferSignatureInstantiationForOverloadFailure(node: CallLikeExpression, typeParameters: readonly TypeParameter[], candidate: Signature, args: readonly Expression[], checkMode: CheckMode ): Signature {
3069830712 const inferenceContext = createInferenceContext(typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
30699- const typeArgumentTypes = inferTypeArguments(node, candidate, args, CheckMode.SkipContextSensitive | CheckMode.SkipGenericFunctions, inferenceContext);
30713+ const typeArgumentTypes = inferTypeArguments(node, candidate, args, checkMode | CheckMode.SkipContextSensitive | CheckMode.SkipGenericFunctions, inferenceContext);
3070030714 return createSignatureInstantiation(candidate, typeArgumentTypes);
3070130715 }
3070230716
0 commit comments