@@ -532,26 +532,13 @@ namespace ts {
532532 if (!node) {
533533 return undefined;
534534 }
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;
535+ if (contextFlags! & ContextFlags.Completions) {
536+ return runWithInferenceBlockedFromSourceNode(node, /*stop*/ undefined, () => getContextualType(node, contextFlags));
553537 }
554- return result;
538+ return getContextualType(node, contextFlags);
539+ },
540+ getContextualTypeForCompletions: (nodeIn: Expression, editingNodeIn: Node) => {
541+ return runWithInferenceBlockedFromSourceNode(editingNodeIn, editingNodeIn, () => getContextualType(nodeIn, ContextFlags.Completions));
555542 },
556543 getContextualTypeForObjectLiteralElement: nodeIn => {
557544 const node = getParseTreeNode(nodeIn, isObjectLiteralElementLike);
@@ -741,33 +728,42 @@ namespace ts {
741728 getMemberOverrideModifierStatus,
742729 };
743730
731+ function runWithInferenceBlockedFromSourceNode<T>(node: Node | undefined, stop: Node | undefined, fn: () => T): T {
732+ const containingCall = findAncestor(stop || node, isCallLikeExpression);
733+ const containingCallResolvedSignature = containingCall && getNodeLinks(containingCall).resolvedSignature;
734+ if (containingCall) {
735+ let toMarkSkip = node!;
736+ do {
737+ getNodeLinks(toMarkSkip).skipDirectInference = true;
738+ toMarkSkip = toMarkSkip.parent;
739+ } while (toMarkSkip && toMarkSkip !== (stop || containingCall));
740+ getNodeLinks(containingCall).resolvedSignature = undefined;
741+ }
742+ const result = fn();
743+ if (containingCall) {
744+ let toMarkSkip = node!;
745+ do {
746+ getNodeLinks(toMarkSkip).skipDirectInference = undefined;
747+ toMarkSkip = toMarkSkip.parent;
748+ } while (toMarkSkip && toMarkSkip !== (stop || containingCall));
749+ getNodeLinks(containingCall).resolvedSignature = containingCallResolvedSignature;
750+ }
751+ return result;
752+ }
753+
744754 function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, checkMode: CheckMode, argumentIndex?: number): Signature | undefined {
745- let node = getParseTreeNode(nodeIn, isCallLikeExpression);
755+ const node = getParseTreeNode(nodeIn, isCallLikeExpression);
756+ let res;
757+ apparentArgumentCount = argumentCount;
746758 if (node && argumentIndex !== undefined) {
747- const replacementArg = setParentRecursive(factory.createAsExpression(factory.createStringLiteral(""), factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword)), /*incremental*/ false);
748- switch (node.kind) {
749- case SyntaxKind.CallExpression:
750- node = factory.updateCallExpression(node, node.expression, node.typeArguments, [
751- ...node.arguments.slice(0, argumentIndex),
752- replacementArg,
753- ...node.arguments.slice(argumentIndex + 1),
754- ]);
755- break;
756- case SyntaxKind.NewExpression:
757- node = factory.updateNewExpression(node, node.expression, node.typeArguments, [
758- ...node.arguments?.slice(0, argumentIndex) || emptyArray,
759- replacementArg,
760- ...node.arguments?.slice(argumentIndex + 1) || emptyArray,
761- ]);
762- break;
763- default:
764- Debug.failBadSyntaxKind(node);
765- }
766- setParent(replacementArg, node);
767- setParent(node, nodeIn.parent);
759+ const editingArgument =
760+ tryCast(node, isCallOrNewExpression)?.arguments?.[argumentIndex] ||
761+ tryCast(node, isJsxOpeningLikeElement)?.attributes?.properties[argumentIndex];
762+ res = runWithInferenceBlockedFromSourceNode(editingArgument, /*stop*/ undefined, () => getResolvedSignature(node, candidatesOutArray, checkMode));
763+ }
764+ else {
765+ res = node ? getResolvedSignature(node, candidatesOutArray, checkMode) : undefined;
768766 }
769- apparentArgumentCount = argumentCount;
770- const res = node ? getResolvedSignature(node, candidatesOutArray, checkMode) : undefined;
771767 apparentArgumentCount = undefined;
772768 return res;
773769 }
@@ -22687,7 +22683,7 @@ namespace ts {
2268722683 const properties = getPropertiesOfObjectType(target);
2268822684 for (const targetProp of properties) {
2268922685 const sourceProp = getPropertyOfType(source, targetProp.escapedName);
22690- if (sourceProp) {
22686+ if (sourceProp && !some(sourceProp.declarations, d => !!getNodeLinks(d).skipDirectInference) ) {
2269122687 inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
2269222688 }
2269322689 }
@@ -29785,7 +29781,7 @@ namespace ts {
2978529781
2978629782 for (let i = 0; i < argCount; i++) {
2978729783 const arg = args[i];
29788- if (arg.kind !== SyntaxKind.OmittedExpression) {
29784+ if (arg.kind !== SyntaxKind.OmittedExpression && !getNodeLinks(arg).skipDirectInference ) {
2978929785 const paramType = getTypeAtPosition(signature, i);
2979029786 const argType = checkExpressionWithContextualType(arg, paramType, context, checkMode);
2979129787 inferTypes(context.inferences, argType, paramType);
0 commit comments