@@ -175,15 +175,16 @@ namespace ts {
175175 }
176176
177177 const enum CheckMode {
178- Normal = 0, // Normal type checking
179- Contextual = 1 << 0, // Explicitly assigned contextual type, therefore not cacheable
180- Inferential = 1 << 1, // Inferential typing
181- SkipContextSensitive = 1 << 2, // Skip context sensitive function expressions
182- SkipGenericFunctions = 1 << 3, // Skip single signature generic functions
183- IsForSignatureHelp = 1 << 4, // Call resolution for purposes of signature help
184- RestBindingElement = 1 << 5, // Checking a type that is going to be used to determine the type of a rest binding element
185- // e.g. in `const { a, ...rest } = foo`, when checking the type of `foo` to determine the type of `rest`,
186- // we need to preserve generic types instead of substituting them for constraints
178+ Normal = 0, // Normal type checking
179+ Contextual = 1 << 0, // Explicitly assigned contextual type, therefore not cacheable
180+ Inferential = 1 << 1, // Inferential typing
181+ SkipContextSensitive = 1 << 2, // Skip context sensitive function expressions
182+ SkipGenericFunctions = 1 << 3, // Skip single signature generic functions
183+ IsForSignatureHelp = 1 << 4, // Call resolution for purposes of signature help
184+ IsForStringLiteralArgumentCompletions = 1 << 5, // Do not infer from the argument currently being typed
185+ RestBindingElement = 1 << 6, // 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
187188 }
188189
189190 const enum SignatureCheckMode {
@@ -532,26 +533,10 @@ namespace ts {
532533 if (!node) {
533534 return undefined;
534535 }
535- const containingCall = findAncestor(node, isCallLikeExpression);
536- const containingCallResolvedSignature = containingCall && getNodeLinks(containingCall).resolvedSignature;
537- if (contextFlags! & ContextFlags.Completions && containingCall) {
538- let toMarkSkip = node as Node;
539- do {
540- getNodeLinks(toMarkSkip).skipDirectInference = true;
541- toMarkSkip = toMarkSkip.parent;
542- } while (toMarkSkip && toMarkSkip !== containingCall);
543- getNodeLinks(containingCall).resolvedSignature = undefined;
544- }
545- const result = getContextualType(node, contextFlags);
546- if (contextFlags! & ContextFlags.Completions && containingCall) {
547- let toMarkSkip = node as Node;
548- do {
549- getNodeLinks(toMarkSkip).skipDirectInference = undefined;
550- toMarkSkip = toMarkSkip.parent;
551- } while (toMarkSkip && toMarkSkip !== containingCall);
552- getNodeLinks(containingCall).resolvedSignature = containingCallResolvedSignature;
536+ if (contextFlags! & ContextFlags.Completions) {
537+ return runWithInferenceBlockedFromSourceNode(node, () => getContextualType(node, contextFlags));
553538 }
554- return result ;
539+ return getContextualType(node, contextFlags) ;
555540 },
556541 getContextualTypeForObjectLiteralElement: nodeIn => {
557542 const node = getParseTreeNode(nodeIn, isObjectLiteralElementLike);
@@ -570,6 +555,8 @@ namespace ts {
570555 getFullyQualifiedName,
571556 getResolvedSignature: (node, candidatesOutArray, argumentCount) =>
572557 getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.Normal),
558+ getResolvedSignatureForStringLiteralCompletions: (call, editingArgument, candidatesOutArray) =>
559+ getResolvedSignatureWorker(call, candidatesOutArray, /*argumentCount*/ undefined, CheckMode.IsForStringLiteralArgumentCompletions, editingArgument),
573560 getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, argumentCount) =>
574561 getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.IsForSignatureHelp),
575562 getExpandedParameters,
@@ -739,10 +726,36 @@ namespace ts {
739726 getMemberOverrideModifierStatus,
740727 };
741728
742- function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, checkMode: CheckMode): Signature | undefined {
729+ function runWithInferenceBlockedFromSourceNode<T>(node: Node | undefined, fn: () => T): T {
730+ const containingCall = findAncestor(node, isCallLikeExpression);
731+ const containingCallResolvedSignature = containingCall && getNodeLinks(containingCall).resolvedSignature;
732+ if (containingCall) {
733+ let toMarkSkip = node!;
734+ do {
735+ getNodeLinks(toMarkSkip).skipDirectInference = true;
736+ toMarkSkip = toMarkSkip.parent;
737+ } while (toMarkSkip && toMarkSkip !== containingCall);
738+ getNodeLinks(containingCall).resolvedSignature = undefined;
739+ }
740+ const result = fn();
741+ if (containingCall) {
742+ let toMarkSkip = node!;
743+ do {
744+ getNodeLinks(toMarkSkip).skipDirectInference = undefined;
745+ toMarkSkip = toMarkSkip.parent;
746+ } while (toMarkSkip && toMarkSkip !== containingCall);
747+ getNodeLinks(containingCall).resolvedSignature = containingCallResolvedSignature;
748+ }
749+ return result;
750+ }
751+
752+ function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, checkMode: CheckMode, editingArgument?: Node): Signature | undefined {
743753 const node = getParseTreeNode(nodeIn, isCallLikeExpression);
744754 apparentArgumentCount = argumentCount;
745- const res = node ? getResolvedSignature(node, candidatesOutArray, checkMode) : undefined;
755+ const res =
756+ !node ? undefined :
757+ editingArgument ? runWithInferenceBlockedFromSourceNode(editingArgument, () => getResolvedSignature(node, candidatesOutArray, checkMode)) :
758+ getResolvedSignature(node, candidatesOutArray, checkMode);
746759 apparentArgumentCount = undefined;
747760 return res;
748761 }
@@ -22662,7 +22675,7 @@ namespace ts {
2266222675 const properties = getPropertiesOfObjectType(target);
2266322676 for (const targetProp of properties) {
2266422677 const sourceProp = getPropertyOfType(source, targetProp.escapedName);
22665- if (sourceProp) {
22678+ if (sourceProp && !some(sourceProp.declarations, hasSkipDirectInferenceFlag) ) {
2266622679 inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
2266722680 }
2266822681 }
@@ -29760,7 +29773,7 @@ namespace ts {
2976029773
2976129774 for (let i = 0; i < argCount; i++) {
2976229775 const arg = args[i];
29763- if (arg.kind !== SyntaxKind.OmittedExpression) {
29776+ if (arg.kind !== SyntaxKind.OmittedExpression && !(checkMode & CheckMode.IsForStringLiteralArgumentCompletions && hasSkipDirectInferenceFlag(arg)) ) {
2976429777 const paramType = getTypeAtPosition(signature, i);
2976529778 const argType = checkExpressionWithContextualType(arg, paramType, context, checkMode);
2976629779 inferTypes(context.inferences, argType, paramType);
@@ -30500,7 +30513,7 @@ namespace ts {
3050030513 }
3050130514 }
3050230515
30503- return getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray);
30516+ return getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray, checkMode );
3050430517
3050530518 function addImplementationSuccessElaboration(failed: Signature, diagnostic: Diagnostic) {
3050630519 const oldCandidatesForArgumentError = candidatesForArgumentError;
@@ -30614,14 +30627,15 @@ namespace ts {
3061430627 candidates: Signature[],
3061530628 args: readonly Expression[],
3061630629 hasCandidatesOutArray: boolean,
30630+ checkMode: CheckMode,
3061730631 ): Signature {
3061830632 Debug.assert(candidates.length > 0); // Else should not have called this.
3061930633 checkNodeDeferred(node);
3062030634 // Normally we will combine overloads. Skip this if they have type parameters since that's hard to combine.
3062130635 // Don't do this if there is a `candidatesOutArray`,
3062230636 // because then we want the chosen best candidate to be one of the overloads, not a combination.
3062330637 return hasCandidatesOutArray || candidates.length === 1 || candidates.some(c => !!c.typeParameters)
30624- ? pickLongestCandidateSignature(node, candidates, args)
30638+ ? pickLongestCandidateSignature(node, candidates, args, checkMode )
3062530639 : createUnionOfSignaturesForOverloadFailure(candidates);
3062630640 }
3062730641
@@ -30675,7 +30689,7 @@ namespace ts {
3067530689 return createSymbolWithType(first(sources), type);
3067630690 }
3067730691
30678- function pickLongestCandidateSignature(node: CallLikeExpression, candidates: Signature[], args: readonly Expression[]): Signature {
30692+ function pickLongestCandidateSignature(node: CallLikeExpression, candidates: Signature[], args: readonly Expression[], checkMode: CheckMode ): Signature {
3067930693 // Pick the longest signature. This way we can get a contextual type for cases like:
3068030694 // declare function f(a: { xa: number; xb: number; }, b: number);
3068130695 // f({ |
@@ -30692,7 +30706,7 @@ namespace ts {
3069230706 const typeArgumentNodes: readonly TypeNode[] | undefined = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments : undefined;
3069330707 const instantiated = typeArgumentNodes
3069430708 ? createSignatureInstantiation(candidate, getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, isInJSFile(node)))
30695- : inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args);
30709+ : inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args, checkMode );
3069630710 candidates[bestIndex] = instantiated;
3069730711 return instantiated;
3069830712 }
@@ -30708,9 +30722,9 @@ namespace ts {
3070830722 return typeArguments;
3070930723 }
3071030724
30711- function inferSignatureInstantiationForOverloadFailure(node: CallLikeExpression, typeParameters: readonly TypeParameter[], candidate: Signature, args: readonly Expression[]): Signature {
30725+ function inferSignatureInstantiationForOverloadFailure(node: CallLikeExpression, typeParameters: readonly TypeParameter[], candidate: Signature, args: readonly Expression[], checkMode: CheckMode ): Signature {
3071230726 const inferenceContext = createInferenceContext(typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
30713- const typeArgumentTypes = inferTypeArguments(node, candidate, args, CheckMode.SkipContextSensitive | CheckMode.SkipGenericFunctions, inferenceContext);
30727+ const typeArgumentTypes = inferTypeArguments(node, candidate, args, checkMode | CheckMode.SkipContextSensitive | CheckMode.SkipGenericFunctions, inferenceContext);
3071430728 return createSignatureInstantiation(candidate, typeArgumentTypes);
3071530729 }
3071630730
0 commit comments