diff --git a/src/services/completions.ts b/src/services/completions.ts index 8a28ae88bb6..6f4cadec7e1 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -185,7 +185,10 @@ namespace ts.Completions { else if (needsConvertPropertyAccess) { // TODO: GH#20619 Use configured quote style insertText = `["${name}"]`; - replacementSpan = createTextSpanFromBounds(findChildOfKind(propertyAccessToConvert!, SyntaxKind.DotToken, sourceFile)!.getStart(sourceFile), propertyAccessToConvert!.name.end); + const dot = findChildOfKind(propertyAccessToConvert!, SyntaxKind.DotToken, sourceFile)!; + // If the text after the '.' starts with this name, write over it. Else, add new text. + const end = startsWith(name, propertyAccessToConvert!.name.text) ? propertyAccessToConvert!.name.end : dot.end; + replacementSpan = createTextSpanFromBounds(dot.getStart(sourceFile), end); } if (isJsxInitializer) { diff --git a/tests/cases/fourslash/completionListInvalidMemberNames_withExistingIdentifier.ts b/tests/cases/fourslash/completionListInvalidMemberNames_withExistingIdentifier.ts index 8463a710b01..3c06692293e 100644 --- a/tests/cases/fourslash/completionListInvalidMemberNames_withExistingIdentifier.ts +++ b/tests/cases/fourslash/completionListInvalidMemberNames_withExistingIdentifier.ts @@ -1,7 +1,10 @@ /// ////declare const x: { "foo ": "space in the name", }; -////x[|.fo/**/|]; +////x[|.fo/*0*/|]; +////x[|./*1*/|] +////unrelatedIdentifier; -const replacementSpan = test.ranges()[0]; -verify.completionsAt("", [{ name: "foo ", insertText: '["foo "]', replacementSpan }], { includeInsertTextCompletions: true }); +const [r0, r1] = test.ranges(); +verify.completionsAt("0", [{ name: "foo ", insertText: '["foo "]', replacementSpan: r0 }], { includeInsertTextCompletions: true }); +verify.completionsAt("1", [{ name: "foo ", insertText: '["foo "]', replacementSpan: r1 }], { includeInsertTextCompletions: true });