diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts
index e9b0f2fc7ed12..881ce7478604b 100644
--- a/src/services/codefixes/fixUnusedIdentifier.ts
+++ b/src/services/codefixes/fixUnusedIdentifier.ts
@@ -3,6 +3,7 @@ import {
CancellationToken,
cast,
CodeFixAction,
+ CodeFixContext,
Debug,
DiagnosticAndArguments,
DiagnosticMessage,
@@ -14,12 +15,15 @@ import {
forEach,
FunctionLikeDeclaration,
getJSDocParameterTags,
+ getNewLineOrDefaultFromHost,
+ getPrecedingNonSpaceCharacterPosition,
getTokenAtPosition,
Identifier,
ImportDeclaration,
isArrayBindingPattern,
isBinaryExpression,
isCallExpression,
+ isCallLikeExpression,
isComputedPropertyName,
isDeclarationWithTypeParameterChildren,
isExpressionStatement,
@@ -37,11 +41,14 @@ import {
isPrefixUnaryExpression,
isPropertyAccessExpression,
isSuperKeyword,
+ isVariableDeclaration,
isVariableDeclarationList,
+ length,
map,
Node,
ObjectBindingPattern,
ParameterDeclaration,
+ probablyUsesSemicolons,
Program,
showModuleSpecifier,
SourceFile,
@@ -114,7 +121,7 @@ registerCodeFix({
}
return [
createDeleteFix(textChanges.ChangeTracker.with(context, t =>
- t.delete(sourceFile, token.parent.parent)), Diagnostics.Remove_unused_destructuring_declaration)
+ deleteDestructuring(context, t, sourceFile, token.parent as ObjectBindingPattern | ArrayBindingPattern)), Diagnostics.Remove_unused_destructuring_declaration),
];
}
@@ -243,6 +250,27 @@ function deleteDestructuringElements(changes: textChanges.ChangeTracker, sourceF
forEach(node.elements, n => changes.delete(sourceFile, n));
}
+function deleteDestructuring(context: CodeFixContext, changes: textChanges.ChangeTracker, sourceFile: SourceFile, { parent }: ObjectBindingPattern | ArrayBindingPattern) {
+ if (isVariableDeclaration(parent) && parent.initializer && isCallLikeExpression(parent.initializer)) {
+ if (isVariableDeclarationList(parent.parent) && length(parent.parent.declarations) > 1) {
+ const varStatement = parent.parent.parent;
+ const pos = varStatement.getStart(sourceFile);
+ const end = varStatement.end;
+ changes.delete(sourceFile, parent);
+ changes.insertNodeAt(sourceFile, end, parent.initializer, {
+ prefix: getNewLineOrDefaultFromHost(context.host, context.formatContext.options) + sourceFile.text.slice(getPrecedingNonSpaceCharacterPosition(sourceFile.text, pos - 1), pos),
+ suffix: probablyUsesSemicolons(sourceFile) ? ";" : "",
+ });
+ }
+ else {
+ changes.replaceNode(sourceFile, parent.parent, parent.initializer);
+ }
+ }
+ else {
+ changes.delete(sourceFile, parent);
+ }
+}
+
function tryPrefixDeclaration(changes: textChanges.ChangeTracker, errorCode: number, sourceFile: SourceFile, token: Node): void {
// Don't offer to prefix a property.
if (errorCode === Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code) return;
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements7.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements7.ts
new file mode 100644
index 0000000000000..e4905ac4445af
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements7.ts
@@ -0,0 +1,20 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////function foo() {
+//// return { a: 1 };
+////}
+////[|function bar() {
+//// const { a } = foo();
+////}|]
+
+verify.codeFix({
+ index: 0,
+ description: ts.Diagnostics.Remove_unused_destructuring_declaration.message,
+ newRangeContent:
+`function bar() {
+ foo();
+}`,
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements8.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements8.ts
new file mode 100644
index 0000000000000..235e5b1b31ef8
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements8.ts
@@ -0,0 +1,24 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////function foo() {
+//// return { a: 1 };
+////}
+////[|function bar() {
+//// const { a } = foo(),
+//// b = 1;
+//// return b;
+////}|]
+
+verify.codeFix({
+ index: 0,
+ description: ts.Diagnostics.Remove_unused_destructuring_declaration.message,
+ newRangeContent:
+`function bar() {
+ const b = 1;
+ foo();
+ return b;
+}`,
+});