Repository: prettier/prettier (JavaScript)

Issue:
Long lines of code need to be formatted twice
**Prettier 2.5.1**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEAbOMAEcC2BLLAXgB0pNzMATOAMzyjgFF8YBnAHmEwAo4A3BDCSZiIAE5wAhpQCeogDSYwkqH0mthACQAqAWQAyAYRVrWjdDkEBKYXwh5KAbh79BSURNZ4AXnAXLVdSQdA2NAswtrJDsHZwBfAD5uK0cQeRAIAAcYPGhWZFBJMTEIAHcABSKEfJRJVFLJGXz0gCMxSTAAawwAZUlLfXo4ZBo61jhW9q7ezI76AHNkGDEAVwmQXBa4SmpKfRV5lcl5uAAxCDEcSRgcqEXalZgINJAACxgcVAB1V4I4VlmYDgPWqBDwfAIMmQ4FYzRA9HGYhg5Xa8yuIzG6wAVqwAB49BboACKKwg8AxqHG6VmYkR0JgMky-zAYjw2RemVZsC+Dhgr2QAA4AAzUkrjL7tTLQzn-OBiAQvACOpPgKKyNRA6gAtAxttsXhJlXgJCjjuikKNKetxvglqtrYS4CSycMLZj0jBJC0eZQ+cgAEwe9p4VALQwQHDmjasACsLxW420XpqlqpID4awAklBqLAeiy2TAAII5noM9AU8ZxOJAA), [second playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEAbOMAEcC2BLLAXgB0pNMATOAMzyjgFF8YBnAHmFPPIAo4A3BDCSZiIAE5wAhhQCeYgDSYwUqPyksRACQAqAWQAyAYVXqWDdDiEBKEfwh4KAbi7c+g2CLGSWeAF5wisqmGtr6xiHmljZ2Ds6uAL4AfDzWTiAKIBAADjB40CzIoFLi4hAA7gAKJQiFKFKo5VKyhZkARuJSYADWGADKUlYGdHDI1A0scO2dPf3ZXXQA5sgw4gCuUyC4bXAUVBQGqotrUotwAGIQ4jhSMHlQy-VrMBAZIAAWMDioAOrvBHAWPMwHA+rUCHh+ARZMhwCxWiA6JNxDBKp1FjcxhNNgArFgADz6S3QAEU1hB4FjUJNMvNxMjYTBZNlAWBxHhcm9suzYD9HDB3sgABwABlpZUmP062Vh3MBcHEgjeAEdyfA0Tk6iANABaei7XZvSSqvCSNGnTFIcbUzaTfArda24lwMkU0ZW7GZGBSNp8igC5AAJi9nTwqCWRggOEtWxYAFY3mtJjofXVrTSQPwNgBJKBUWB9NkcmAAQTzfSZ6CpkwSCSAA)

<!-- prettier-ignore -->
```sh
--parser typescript
```

**Input:**
<!-- prettier-ignore -->
```tsx
let emit =
    defineEmits<{ (event: "ready", canvas: HTMLCanvasElement): void; (event:"resize",canvas:HTMLCanvasElement):void; }>();
```

**Output:**
<!-- prettier-ignore -->
```tsx
let emit =
  defineEmits<{
    (event: "ready", canvas: HTMLCanvasElement): void;
    (event: "resize", canvas: HTMLCanvasElement): void;
  }>();

```

**Output upon reformatting:**
<!-- prettier-ignore -->
```tsx
let emit = defineEmits<{
  (event: "ready", canvas: HTMLCanvasElement): void;
  (event: "resize", canvas: HTMLCanvasElement): void;
}>();

```

**Issue:**
Upon reformatting the code, Prettier gives a different response than the original.

**Expected behavior:**
Prettier should only require a single formatting to correctly format the code.


Hints:
I've noticed this is often an issue when combining TypeScript generics with object literals. Here's a second example for reference:

**Prettier 2.5.1**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEAzArlMMCW0AEGWAPACoB8AFAJT7AC+AOlMwDZwz4CGARmALzN8w4UTDFgXJACYANDyQBmWQBMkAdgAcsuEgCcs1Em0BzDbIAWSAGyycSAKyyAVkgAssgNZLZrGbIBbJABGWSgkAAZZCH1ZAAdjWQBHcwAnG1kAZ0dZGHdZdB8AN38AdxDZAA9I2QBPWIAvY3oqagBuEFkQCDjcaEzkUC5U1IhSgAVhhAGULlZSrlqBrp5UrjBPDgBlLgC4ABkcKDhkVDnMuBW1je249aOTZBhU9EuQOACeOBUVb-2uKAmdBcExwABiEFSAS4MFwgOQIC46BgEE6IAsMACrAA6hYcPBMncwHAttN8TgivjagiwJlliAjhdUjBxmsTNDTuc3s5MpUtg92ABFdAQeCc1gXLp3VJMhEwWpxOCZMCpHC9NFxVWwbE4FQwCzITRRECaiAXbFrOIIzVKuCpIonLpJEXwVk9GaIzIAWmO32+aNScGdOEDrJBHKQZwlbwuARwTxeMYFcGFopOka5XRgvB1eoN-hAzy4OFYDwAwhAAhH3pkHGj0BdSLwZlHJSAiq8AJJQX6wLYqtUwACCPa28vY4ou9HoQA), [Second playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEAzArlMMCW0AEGWAPACoB8AFAJT7AC+AOlMwDZwz4CGARmPgF5m+QpjDFgwkdyT4ATAG4pInrIDMSqNPwATWQHYAHJu1xZAThPTUs48vwBzA1ZEALWQDYX+HLICs3gBWsgAs3gDW6t6ssor2ALayAIzeULIADN4QFt4ADrbeAI7O9gBOnt4Azv7eMKHe6FH2AG6x3gDuyd4AHhneAJ459gBeBVL0VNSaIAA0IBC5uNCVyKBcpaUQ7QAK6wgrKFys7Vz9K3M8pVxg4RwAylzxcAAyOFBwyKhHlXAXVzf3XLXN4OZAwUroX4gODxHhwHQ6eHPLhQBzoLgOOAAMQgpXiXBguFRyBAXHQMAgsxArhg8VYAHVXDh4JUgWA4Hd9sycM1mf0SWBKucQG8fqUYNsrg58Z9vlDApVuncQewAIroCDwWWsH5zIGlMUkmD9XJwSpgUo4RZU3KW2D0nA6GCuZCGdJ6zY-elXXIk21muClZofOaFDXwSULA6kyoAWne8PhVNKcDDOBTkoxMqQXx1UJ+8RwYIh+ZVcHVmo+OblcxgvAdTpdSDktauOFYIIAwhB4tnoZU-FT0D9SLwDrndSBmpCAJJQRGwO4Wq0wACC87uxvY2p+9HoQA)
<!-- prettier-ignore -->
```sh
--parser typescript
```

**Input:**
<!-- prettier-ignore -->
```tsx
function func<T>() {}

let abc=
     func<{a:2,b:3,d:78,e:9,f:8,g:7,h:6,i:5,j:4,k:3,l:2,m:1,n:0,o:9,p:8,q:7,r:6,s:5,t:4,u:3,v:2,w:1,x:0,y:9,z:8}>();
```

**Output:**
<!-- prettier-ignore -->
```tsx
function func<T>() {}

let abc =
  func<{
    a: 2;
    b: 3;
    d: 78;
    e: 9;
    f: 8;
    g: 7;
    h: 6;
    i: 5;
    j: 4;
    k: 3;
    l: 2;
    m: 1;
    n: 0;
    o: 9;
    p: 8;
    q: 7;
    r: 6;
    s: 5;
    t: 4;
    u: 3;
    v: 2;
    w: 1;
    x: 0;
    y: 9;
    z: 8;
  }>();

```

**Output upon reformatting:**
<!-- prettier-ignore -->
```tsx
function func<T>() {}

let abc = func<{
  a: 2;
  b: 3;
  d: 78;
  e: 9;
  f: 8;
  g: 7;
  h: 6;
  i: 5;
  j: 4;
  k: 3;
  l: 2;
  m: 1;
  n: 0;
  o: 9;
  p: 8;
  q: 7;
  r: 6;
  s: 5;
  t: 4;
  u: 3;
  v: 2;
  w: 1;
  x: 0;
  y: 9;
  z: 8;
}>();

```

**Expected behavior:**
This is another example where Prettier requires two passes to format the code correctly.

Patch:
diff --git a/src/language-js/print/assignment.js b/src/language-js/print/assignment.js
--- a/src/language-js/print/assignment.js
+++ b/src/language-js/print/assignment.js
@@ -441,7 +441,9 @@ function isCallExpressionWithComplexTypeArguments(node, print) {
         firstArg.type === "TSUnionType" ||
         firstArg.type === "UnionTypeAnnotation" ||
         firstArg.type === "TSIntersectionType" ||
-        firstArg.type === "IntersectionTypeAnnotation"
+        firstArg.type === "IntersectionTypeAnnotation" ||
+        firstArg.type === "TSTypeLiteral" ||
+        firstArg.type === "ObjectTypeAnnotation"
       ) {
         return true;
       }


Test patch:
diff --git a/tests/format/flow/assignments/__snapshots__/jsfmt.spec.js.snap b/tests/format/flow/assignments/__snapshots__/jsfmt.spec.js.snap
--- a/tests/format/flow/assignments/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/flow/assignments/__snapshots__/jsfmt.spec.js.snap
@@ -110,3 +110,52 @@ const map: Map<Function, Foo<S>> = new Map();
 
 ================================================================================
 `;
+
+exports[`issue-12413.js format 1`] = `
+====================================options=====================================
+parsers: ["babel-flow", "flow"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+let emit =
+  defineEmits<{ (event: "ready", canvas: HTMLCanvasElement): void; (event:"resize",canvas:HTMLCanvasElement):void; }>();
+
+let abc =
+  func<{a:2,b:3,d:78,e:9,f:8,g:7,h:6,i:5,j:4,k:3,l:2,m:1,n:0,o:9,p:8,q:7,r:6,s:5,t:4,u:3,v:2,w:1,x:0,y:9,z:8}>();
+
+=====================================output=====================================
+let emit = defineEmits<{
+  (event: "ready", canvas: HTMLCanvasElement): void,
+  (event: "resize", canvas: HTMLCanvasElement): void,
+}>();
+
+let abc = func<{
+  a: 2,
+  b: 3,
+  d: 78,
+  e: 9,
+  f: 8,
+  g: 7,
+  h: 6,
+  i: 5,
+  j: 4,
+  k: 3,
+  l: 2,
+  m: 1,
+  n: 0,
+  o: 9,
+  p: 8,
+  q: 7,
+  r: 6,
+  s: 5,
+  t: 4,
+  u: 3,
+  v: 2,
+  w: 1,
+  x: 0,
+  y: 9,
+  z: 8,
+}>();
+
+================================================================================
+`;
diff --git a/tests/format/flow/assignments/issue-12413.js b/tests/format/flow/assignments/issue-12413.js
new file mode 100644
--- /dev/null
+++ b/tests/format/flow/assignments/issue-12413.js
@@ -0,0 +1,5 @@
+let emit =
+  defineEmits<{ (event: "ready", canvas: HTMLCanvasElement): void; (event:"resize",canvas:HTMLCanvasElement):void; }>();
+
+let abc =
+  func<{a:2,b:3,d:78,e:9,f:8,g:7,h:6,i:5,j:4,k:3,l:2,m:1,n:0,o:9,p:8,q:7,r:6,s:5,t:4,u:3,v:2,w:1,x:0,y:9,z:8}>();
diff --git a/tests/format/typescript/assignment/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/assignment/__snapshots__/jsfmt.spec.js.snap
--- a/tests/format/typescript/assignment/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/typescript/assignment/__snapshots__/jsfmt.spec.js.snap
@@ -443,6 +443,55 @@ const map: Map<Function, Foo<S>> = new Map();
 ================================================================================
 `;
 
+exports[`issue-12413.ts format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+let emit =
+  defineEmits<{ (event: "ready", canvas: HTMLCanvasElement): void; (event:"resize",canvas:HTMLCanvasElement):void; }>();
+
+let abc =
+  func<{a:2,b:3,d:78,e:9,f:8,g:7,h:6,i:5,j:4,k:3,l:2,m:1,n:0,o:9,p:8,q:7,r:6,s:5,t:4,u:3,v:2,w:1,x:0,y:9,z:8}>();
+
+=====================================output=====================================
+let emit = defineEmits<{
+  (event: "ready", canvas: HTMLCanvasElement): void;
+  (event: "resize", canvas: HTMLCanvasElement): void;
+}>();
+
+let abc = func<{
+  a: 2;
+  b: 3;
+  d: 78;
+  e: 9;
+  f: 8;
+  g: 7;
+  h: 6;
+  i: 5;
+  j: 4;
+  k: 3;
+  l: 2;
+  m: 1;
+  n: 0;
+  o: 9;
+  p: 8;
+  q: 7;
+  r: 6;
+  s: 5;
+  t: 4;
+  u: 3;
+  v: 2;
+  w: 1;
+  x: 0;
+  y: 9;
+  z: 8;
+}>();
+
+================================================================================
+`;
+
 exports[`lone-arg.ts format 1`] = `
 ====================================options=====================================
 parsers: ["typescript"]
diff --git a/tests/format/typescript/assignment/issue-12413.ts b/tests/format/typescript/assignment/issue-12413.ts
new file mode 100644
--- /dev/null
+++ b/tests/format/typescript/assignment/issue-12413.ts
@@ -0,0 +1,5 @@
+let emit =
+  defineEmits<{ (event: "ready", canvas: HTMLCanvasElement): void; (event:"resize",canvas:HTMLCanvasElement):void; }>();
+
+let abc =
+  func<{a:2,b:3,d:78,e:9,f:8,g:7,h:6,i:5,j:4,k:3,l:2,m:1,n:0,o:9,p:8,q:7,r:6,s:5,t:4,u:3,v:2,w:1,x:0,y:9,z:8}>();