diff --git a/src/services/refactors/convertStringOrTemplateLiteral.ts b/src/services/refactors/convertStringOrTemplateLiteral.ts
index bbc825c3d00..423e15b88f1 100644
--- a/src/services/refactors/convertStringOrTemplateLiteral.ts
+++ b/src/services/refactors/convertStringOrTemplateLiteral.ts
@@ -9,6 +9,7 @@ namespace ts.refactor.convertStringOrTemplateLiteral {
const toStringConcatenationDescription = getLocaleSpecificMessage(Diagnostics.Convert_to_string_concatenation);
// TODO let a = 45 + 45 + " ee" + 33;
+ // TODO let a = 45 - 45 + " ee" - 33;
// TODO let a = tag `aaa`;
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
@@ -19,22 +20,17 @@ namespace ts.refactor.convertStringOrTemplateLiteral {
const maybeBinary = getParentBinaryExpression(node); containsString(maybeBinary);
const actions: RefactorActionInfo[] = [];
- if (!isTemplateLike(node) && (isBinaryExpression(maybeBinary) || isStringLiteral(maybeBinary)) && containsString(maybeBinary)) {
+ if ((isBinaryExpression(maybeBinary) || isStringLiteral(maybeBinary)) && containsString(maybeBinary)) {
actions.push({ name: toTemplateLiteralActionName, description: toTemplateLiteralDescription });
}
-
- if (isTemplateLike(node)) {
+ if (isNoSubstitutionTemplateLiteral(node) || isTemplateHead(node) || isTemplateSpan(node.parent)) {
actions.push({ name: toStringConcatenationActionName, description: toStringConcatenationDescription });
}
return [{ name: refactorName, description: refactorDescription, actions }];
}
- function isTemplateLike(node: Node): boolean {
- return isNoSubstitutionTemplateLiteral(node) || isTemplateHead(node) || isTemplateMiddleOrTemplateTail(node);
- }
-
function getEditsForAction(context: RefactorContext, actionName: string): RefactorEditInfo | undefined {
const { file, startPosition } = context;
const node = getTokenAtPosition(file, startPosition);
@@ -55,8 +51,8 @@ namespace ts.refactor.convertStringOrTemplateLiteral {
return { edits: textChanges.ChangeTracker.with(context, t => t.replaceNode(file, node, stringLiteral)) };
}
- if (isTemplateExpression(node.parent)) {
- const templateLiteralExpression = node.parent;
+ if (isTemplateExpression(node.parent) || isTemplateSpan(node.parent)) {
+ const templateLiteralExpression = isTemplateSpan(node.parent) ? node.parent.parent : node.parent;
const nodesArray: Expression[] = [];
if (templateLiteralExpression.head.text.length !== 0) nodesArray.push(createStringLiteral(templateLiteralExpression.head.text));
diff --git a/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringAvailability.ts b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringAvailability.ts
index 6ce188ac438..3831d443735 100644
--- a/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringAvailability.ts
+++ b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringAvailability.ts
@@ -21,7 +21,7 @@ verify.refactorAvailable("Convert string concatenation or template literal", "Co
verify.not.refactorAvailable("Convert string concatenation or template literal", "Convert to template literal");
goTo.select("r", "q");
-verify.not.refactorAvailable("Convert string concatenation or template literal", "Convert to string concatenation");
+verify.refactorAvailable("Convert string concatenation or template literal", "Convert to string concatenation");
verify.not.refactorAvailable("Convert string concatenation or template literal", "Convert to template literal");
goTo.select("p", "o");
diff --git a/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringSelectedFromExpr.ts b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringSelectedFromExpr.ts
new file mode 100644
index 00000000000..7229e9e9f7a
--- /dev/null
+++ b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringSelectedFromExpr.ts
@@ -0,0 +1,14 @@
+///
+
+//// const age = 42
+//// const foo = `foobar is ${ /*x*/a/*y*/ge } years old`
+
+goTo.select("x", "y");
+edit.applyRefactor({
+ refactorName: "Convert string concatenation or template literal",
+ actionName: "Convert to string concatenation",
+ actionDescription: "Convert to string concatenation",
+ newContent:
+`const age = 42
+const foo = "foobar is " + age + " years old"`,
+});
diff --git a/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringSelectedFromMiddle.ts b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringSelectedFromMiddle.ts
new file mode 100644
index 00000000000..c44e4ee646f
--- /dev/null
+++ b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringSelectedFromMiddle.ts
@@ -0,0 +1,14 @@
+///
+
+//// const age = 42
+//// const foo = `foobar is ${ age } /*x*/y/*y*/ears old ${ false }`
+
+goTo.select("x", "y");
+edit.applyRefactor({
+ refactorName: "Convert string concatenation or template literal",
+ actionName: "Convert to string concatenation",
+ actionDescription: "Convert to string concatenation",
+ newContent:
+`const age = 42
+const foo = "foobar is " + age + " years old " + false`,
+});