Repository: prettier/prettier (JavaScript)
Date: 2020-10-23 08:11:19+00:00
Task type: Bug Fix

Issue:
Inconsistent output of `return assign` between `babel` and `ts`
<!--

BEFORE SUBMITTING AN ISSUE:

1.  Search for your issue on GitHub: https://github.com/prettier/prettier/issues
    A large number of opened issues are duplicates of existing issues.
    If someone has already opened an issue for what you are experiencing,
    you do not need to open a new issue — please add a 👍 reaction to the
    existing issue instead.

2.  We get a lot of requests for adding options, but Prettier is
    built on the principle of being opinionated about code formatting.
    This means we have a very high bar for adding new options.
    Find out more: https://prettier.io/docs/en/option-philosophy.html

Tip! Don't write this stuff manually.

1. Go to https://prettier.io/playground
2. Paste your code and set options
3. Press the "Report issue" button in the lower right

-->

**Prettier 2.1.2**

[TS Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEBbAhgBwBTYNoBOcAzhAK4FhwC6AlAAQC8AfPdsADpT31GkVUkbGAAsAlsQB0fcpThNeJWVVoAaLgF9atEKpARMMMdGLJQ6AgQgB3AAoWEplOgA219AE9TegEYF0YADWcDAAypgBYlAA5sgwBGRwenCoPnAAJukZADLoMWTo0XAAYhAEGDBGMcgg6GQwELogIjCoLgDq4vDEEVShjmJGAG6DHjVgxN4gUcRwBDC2-tEYyABmrrN6AFbEAB4AQv5BIaHoqHDZUXBrG0kgO7uhUdEucACKZBDwNy6bIBEEWYEGowDyYEhgAhiQxNTBQ2DtMTpUTIAAcAAY9HCILN2v5MDU4SQ5kNrnoAI6feCLAxOWrEAC0UDgGQyTSIlLEREWhRWSHWvzus1QYjiCSFz1eHy+135tz0MHQPkRyJEyAATAr-GIXM8AMIQVB8kAkACsTTIswAKkqnAK-kNEgBJKBZWChSHQmAAQVdoVBrx+sw0GiAA)

**Input:**

```ts
map(([resource]) => ({
  resource: (this.resource = resource),
}))
```

**Output:**

```ts
map(([resource]) => ({
  resource: this.resource = resource,
}));
```

**Expected behavior:**

```js
map(([resource]) => ({
  resource: (this.resource = resource),
}));
```

[Babel Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEBbAhgBwBTYNoBOcAzhAK4FhwC6AlAAQC8AfPdsADpT31GkVUkbGAAsAlsQB0fcpThNeJWVVoAaLgF9atEKpARMMMdGLJQ6AgQgB3AAoWEplOgA219AE9TegEYF0YADWcDAAypgBYlAA5sgwBGRwenCoPnAAJukZADLoMWTo0XAAYhAEGDBGMcgg6GQwELogIjCoLgDq4vDEEVShjmJGAG6DHjVgxN4gUcRwBDC2-tEYyABmrrN6AFbEAB4AQv5BIaHoqHDZUXBrG0kgO7uhUdEucACKZBDwNy6bIBEEWYEGo+dBpFxNTAEKIwdpidKiZAADgADHooRBZu1-JgalCSHMhtc9ABHT7wRYGJy1YgAWigcAyGSaRDJYiIi0KKyQ61+d1mqDEcQS-Oerw+X2uPNuehgYLhCJEyAATLL-GIXM8AMIQVDckAkACsTTIswAKmCnLy-kNEgBJKBZWChMDQwwAQUdoRgHleP1mGg0QA)


Issue discussion:

Solution patch:
diff --git a/changelog_unreleased/typescript/pr-9484.md b/changelog_unreleased/typescript/pr-9484.md
new file mode 100644
index 000000000000..1c468a631bcc
--- /dev/null
+++ b/changelog_unreleased/typescript/pr-9484.md
@@ -0,0 +1,13 @@
+#### Add parens to object value that it's an assignment (#9484 by @fisker)
+
+<!-- prettier-ignore -->
+```ts
+// Input
+foo = { bar: (a = b) };
+
+// Prettier master
+foo = { bar: a = b };
+
+// Prettier stable
+foo = { bar: (a = b) };
+```
diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js
index 67e81d26b3fa..21dda13066d6 100644
--- a/src/language-js/needs-parens.js
+++ b/src/language-js/needs-parens.js
@@ -527,7 +527,13 @@ function needsParens(path, options) {
         (grandParent.init === parent || grandParent.update === parent)
       ) {
         return false;
-      } else if (parent.type === "Property" && parent.value === node) {
+      } else if (
+        parent.type === "Property" &&
+        parent.value === node &&
+        grandParent &&
+        grandParent.type === "ObjectPattern" &&
+        grandParent.properties.includes(parent)
+      ) {
         return false;
       } else if (parent.type === "NGChainedExpression") {
         return false;


Test patch:
diff --git a/tests/js/objects/assignment-expression/__snapshots__/jsfmt.spec.js.snap b/tests/js/objects/assignment-expression/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000000..8bd9f1527c0e
--- /dev/null
+++ b/tests/js/objects/assignment-expression/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,45 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`object-property.js format 1`] = `
+====================================options=====================================
+parsers: ["babel", "flow", "typescript"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+a = {
+  [this.resource = resource]: 1,
+}
+
+=====================================output=====================================
+a = {
+  [(this.resource = resource)]: 1,
+};
+
+================================================================================
+`;
+
+exports[`object-value.js format 1`] = `
+====================================options=====================================
+parsers: ["babel", "flow", "typescript"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+a = {
+  resource: (this.resource = resource),
+}
+
+map(([resource]) => ({
+  resource: (this.resource = resource),
+}))
+
+=====================================output=====================================
+a = {
+  resource: (this.resource = resource),
+};
+
+map(([resource]) => ({
+  resource: (this.resource = resource),
+}));
+
+================================================================================
+`;
diff --git a/tests/js/objects/assignment-expression/jsfmt.spec.js b/tests/js/objects/assignment-expression/jsfmt.spec.js
new file mode 100644
index 000000000000..eb85eda6bd02
--- /dev/null
+++ b/tests/js/objects/assignment-expression/jsfmt.spec.js
@@ -0,0 +1,1 @@
+run_spec(__dirname, ["babel", "flow", "typescript"]);
diff --git a/tests/js/objects/assignment-expression/object-property.js b/tests/js/objects/assignment-expression/object-property.js
new file mode 100644
index 000000000000..820ec4ada53f
--- /dev/null
+++ b/tests/js/objects/assignment-expression/object-property.js
@@ -0,0 +1,3 @@
+a = {
+  [this.resource = resource]: 1,
+}
diff --git a/tests/js/objects/assignment-expression/object-value.js b/tests/js/objects/assignment-expression/object-value.js
new file mode 100644
index 000000000000..62a64c6c1c40
--- /dev/null
+++ b/tests/js/objects/assignment-expression/object-value.js
@@ -0,0 +1,7 @@
+a = {
+  resource: (this.resource = resource),
+}
+
+map(([resource]) => ({
+  resource: (this.resource = resource),
+}))