diff --git a/src/services/refactors/convertStringOrTemplateLiteral.ts b/src/services/refactors/convertStringOrTemplateLiteral.ts
index be6d088ff29..08f45aacb24 100644
--- a/src/services/refactors/convertStringOrTemplateLiteral.ts
+++ b/src/services/refactors/convertStringOrTemplateLiteral.ts
@@ -9,7 +9,6 @@ namespace ts.refactor.convertStringOrTemplateLiteral {
const toStringConcatenationDescription = getLocaleSpecificMessage(Diagnostics.Convert_to_string_concatenation);
// TODO let a = 45 - 45 + " ee" - 33;
- // TODO let a = tag `aaa`;
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
@@ -17,13 +16,14 @@ namespace ts.refactor.convertStringOrTemplateLiteral {
const { file, startPosition } = context;
const node = getTokenAtPosition(file, startPosition);
const maybeBinary = getParentBinaryExpression(node); containsString(maybeBinary);
+ const maybeTemplateExpression = findAncestor(node, n => isTemplateExpression(n));
const actions: RefactorActionInfo[] = [];
if ((isBinaryExpression(maybeBinary) || isStringLiteral(maybeBinary)) && containsString(maybeBinary)) {
actions.push({ name: toTemplateLiteralActionName, description: toTemplateLiteralDescription });
}
- if (isNoSubstitutionTemplateLiteral(node) || isTemplateHead(node) || isTemplateSpan(node.parent)) {
+ if ((isNoSubstitutionTemplateLiteral(node) && !isTaggedTemplateExpression(node.parent)) || (maybeTemplateExpression && !isTaggedTemplateExpression(maybeTemplateExpression.parent))) {
actions.push({ name: toStringConcatenationActionName, description: toStringConcatenationDescription });
}
@@ -46,8 +46,7 @@ namespace ts.refactor.convertStringOrTemplateLiteral {
case toStringConcatenationActionName:
if (isNoSubstitutionTemplateLiteral(node)) {
const stringLiteral = createStringLiteral(node.text);
-
- return { edits: textChanges.ChangeTracker.with(context, t => t.replaceNode(file, node, stringLiteral)) };
+ return { edits: textChanges.ChangeTracker.with(context, t => t.replaceNode(file, node, stringLiteral)) };
}
if (isTemplateExpression(node.parent) || isTemplateSpan(node.parent)) {
diff --git a/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringAvailability.ts b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringAvailability.ts
index 3831d443735..a4b6be74631 100644
--- a/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringAvailability.ts
+++ b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringAvailability.ts
@@ -27,4 +27,3 @@ verify.not.refactorAvailable("Convert string concatenation or template literal",
goTo.select("p", "o");
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");
-
diff --git a/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringTaggedAvailability.ts b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringTaggedAvailability.ts
new file mode 100644
index 00000000000..9327ff0911c
--- /dev/null
+++ b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToStringTaggedAvailability.ts
@@ -0,0 +1,17 @@
+///
+
+//// function tag(literals: TemplateStringsArray, ...placeholders: string[]) { return "tagged" }
+//// const alpha = tag/*z*/`/*y*/foobar`
+//// const beta = tag/*x*/`/*w*/foobar ${/*v*/4/*u*/2}`
+
+goTo.select("z", "y");
+verify.not.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("x", "w");
+verify.not.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("v", "u");
+verify.not.refactorAvailable("Convert string concatenation or template literal", "Convert to string concatenation");
+verify.not.refactorAvailable("Convert string concatenation or template literal", "Convert to template literal");
diff --git a/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToTemplatePrefixExpr.ts b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToTemplatePrefixExpr.ts
new file mode 100644
index 00000000000..dfaa3ab8d66
--- /dev/null
+++ b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_ToTemplatePrefixExpr.ts
@@ -0,0 +1,12 @@
+///
+
+//// const foo = /*x*/4/*y*/2 + 6 + 23 + 12 +" years old"
+
+goTo.select("x", "y");
+edit.applyRefactor({
+ refactorName: "Convert string concatenation or template literal",
+ actionName: "Convert to template literal",
+ actionDescription: "Convert to template literal",
+ newContent:
+`const foo = \`\${42 + 6 + 23 + 12} years old\``,
+});