@@ -532,26 +532,13 @@ namespace ts {
532
532
if (!node) {
533
533
return undefined;
534
534
}
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));
553
537
}
554
- return result;
538
+ return getContextualType(node, contextFlags);
539
+ },
540
+ getContextualTypeForCompletions: (nodeIn: Expression, editingNodeIn: Node) => {
541
+ return runWithInferenceBlockedFromSourceNode(editingNodeIn, editingNodeIn, () => getContextualType(nodeIn, ContextFlags.Completions));
555
542
},
556
543
getContextualTypeForObjectLiteralElement: nodeIn => {
557
544
const node = getParseTreeNode(nodeIn, isObjectLiteralElementLike);
@@ -741,33 +728,42 @@ namespace ts {
741
728
getMemberOverrideModifierStatus,
742
729
};
743
730
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
+
744
754
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;
746
758
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;
768
766
}
769
- apparentArgumentCount = argumentCount;
770
- const res = node ? getResolvedSignature(node, candidatesOutArray, checkMode) : undefined;
771
767
apparentArgumentCount = undefined;
772
768
return res;
773
769
}
@@ -22687,7 +22683,7 @@ namespace ts {
22687
22683
const properties = getPropertiesOfObjectType(target);
22688
22684
for (const targetProp of properties) {
22689
22685
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
22690
- if (sourceProp) {
22686
+ if (sourceProp && !some(sourceProp.declarations, d => !!getNodeLinks(d).skipDirectInference) ) {
22691
22687
inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
22692
22688
}
22693
22689
}
@@ -29785,7 +29781,7 @@ namespace ts {
29785
29781
29786
29782
for (let i = 0; i < argCount; i++) {
29787
29783
const arg = args[i];
29788
- if (arg.kind !== SyntaxKind.OmittedExpression) {
29784
+ if (arg.kind !== SyntaxKind.OmittedExpression && !getNodeLinks(arg).skipDirectInference ) {
29789
29785
const paramType = getTypeAtPosition(signature, i);
29790
29786
const argType = checkExpressionWithContextualType(arg, paramType, context, checkMode);
29791
29787
inferTypes(context.inferences, argType, paramType);
0 commit comments