Repository: prettier/prettier (JavaScript)
Date: 2022-12-28 11:59:30+00:00
Task type: Bug Fix

Issue:
[flow] broken code emitted for type annotation with empty type parameters when the value is an arrow function and `arrow-parens: 'avoid'`
**Prettier 2.7.1**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuc0DOMAEAPXf8GFHGFI4kW4A8AfJgLwA6UmmAhgE4DmDdUArgBtBAbhAAaEBAAOMAJbpkoThwgB3AAqcEaZCDYA3CHIAmEkACMObMAGs4MAMpsAtnAAycqHGQAzNoJocJJWNvZO0jZeXMgwHPzBIHAuFnAmJmnubFBc-GxccABiEBwubDDyOXps-DAQ5gAWMC6CAOoNcvBokWBwjjqdcgadAJ56YGi6kl5BHDAa1lxlfgFBkgBWaNiO0YJwAIr8EPArgYmRHLN6voLq5tIcXjCtpjANyAAcAAySDxBBrWs0j0DzgswMPkkAEcjvAFjJdCg2GgALTeNJpcwcOAwuTYhb5ZZIfxnSRBFxyWLxRJoXYHWE+JBxBKSGBsCwvExvZAAJlZ1jkgmiAGEIC4ifphOZ+EEACrsxEktYgAwJACSUAysEcYEesgAgprHDARntTkEAL4WoA)
<!-- prettier-ignore -->
```sh
--parser flow
--arrow-parens avoid
--trailing-comma all
```

**Input:**
<!-- prettier-ignore -->
```jsx
const xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxx<> =
  arg => null;
```

**Output:**
<!-- prettier-ignore -->
```jsx
const xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxx<
  ,
> = arg => null;

```

**Expected behavior:**

Not-broken code. I'd suggest probably:
```jsx
const xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxx<> =
  arg => null;
```


Issue discussion:
It's worth noting that the same code emits correctly [for `typescript`](https://prettier.io/playground/#N4Igxg9gdgLgprEAuc0DOMAEAPXf8GFHGFI4kW4A8AfJgLwA6UmmAhgE4DmDdUArgBtBAbhAAaEBAAOMAJbpkoThwgB3AAqcEaZCDYA3CHIAmEkACMObMAGs4MAMpsAtnAAycqHGQAzNoJocJJWNvZO0jZeXMgwHPzBIHAuFnAmJmnubFBc-GxccABiEBwubDDyOXps-DAQ5gAWMC6CAOoNcvBokWBwjjqdcgadAJ56YGi6kl5BHDAa1lxlfgFBkgBWaNiO0YJwAIr8EPArgYmRHLN6MCPScGhgHHKy5tJPsK2mMA3IABwADJI3hAgq1rNI9G97nAOAYfJIAI5HeALGS6FBsNAAWm8aTS5g4cCRckJC3yyyQ-jOkiCLjksXiiTQuwOyJ8SDiCUkMDYFk+Jm+yAATNzrHJBNEAMIQFwU-TCcz8IIAFV56KpaxABgSAEkoBlYI5Hs8YABBfWOG57U5BAC+tqAA) and `babel-ts`, but not `babel`, `babel-flow`, or `flow`.

However the output for the TS parsers is pretty ugly - it includes an empty line!
```ts
const xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxx<

> = arg => null;
```

Solution patch:
diff --git a/changelog_unreleased/flow/14073.md b/changelog_unreleased/flow/14073.md
new file mode 100644
index 000000000000..8e6f005711c9
--- /dev/null
+++ b/changelog_unreleased/flow/14073.md
@@ -0,0 +1,13 @@
+#### Fix formatting of empty type parameters (#14073 by @fisker)
+
+<!-- prettier-ignore -->
+```jsx
+// Input
+const foo: bar</* comment */> = () => baz;
+
+// Prettier stable
+Error: Comment "comment" was not printed. Please report this error!
+
+// Prettier main
+const foo: bar</* comment */> = () => baz;
+```
diff --git a/src/language-js/print/type-parameters.js b/src/language-js/print/type-parameters.js
index ce1256325507..154ffb161a5a 100644
--- a/src/language-js/print/type-parameters.js
+++ b/src/language-js/print/type-parameters.js
@@ -44,12 +44,12 @@ function printTypeParameters(path, options, print, paramsKey) {
   );
 
   const shouldInline =
-    !isArrowFunctionVariable &&
-    (isParameterInTestCall ||
-      node[paramsKey].length === 0 ||
-      (node[paramsKey].length === 1 &&
-        (node[paramsKey][0].type === "NullableTypeAnnotation" ||
-          shouldHugType(node[paramsKey][0]))));
+    node[paramsKey].length === 0 ||
+    (!isArrowFunctionVariable &&
+      (isParameterInTestCall ||
+        (node[paramsKey].length === 1 &&
+          (node[paramsKey][0].type === "NullableTypeAnnotation" ||
+            shouldHugType(node[paramsKey][0])))));
 
   if (shouldInline) {
     return [


Test patch:
diff --git a/tests/format/typescript/typeparams/empty-parameters-with-arrow-function/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/typeparams/empty-parameters-with-arrow-function/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000000..b3ba94b7dfa8
--- /dev/null
+++ b/tests/format/typescript/typeparams/empty-parameters-with-arrow-function/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,35 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`issue-13817.ts - {"arrowParens":"avoid","trailingComma":"all"} format 1`] = `
+====================================options=====================================
+arrowParens: "avoid"
+parsers: ["typescript", "flow", "babel-flow"]
+printWidth: 80
+trailingComma: "all"
+                                                                                | printWidth
+=====================================input======================================
+const xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxx<> =
+  arg => null;
+
+const xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxx</* comment */> =
+  arg => null;
+
+
+const xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxx<
+  // comment
+> =
+  arg => null;
+
+=====================================output=====================================
+const xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxx<> =
+  arg => null;
+
+const xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxx</* comment */> =
+  arg => null;
+
+const xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxx<
+  // comment
+> = arg => null;
+
+================================================================================
+`;
diff --git a/tests/format/typescript/typeparams/empty-parameters-with-arrow-function/issue-13817.ts b/tests/format/typescript/typeparams/empty-parameters-with-arrow-function/issue-13817.ts
new file mode 100644
index 000000000000..de3013df4f94
--- /dev/null
+++ b/tests/format/typescript/typeparams/empty-parameters-with-arrow-function/issue-13817.ts
@@ -0,0 +1,11 @@
+const xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxx<> =
+  arg => null;
+
+const xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxx</* comment */> =
+  arg => null;
+
+
+const xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: xxxxxxxxxxxxxxxxxxxxxx<
+  // comment
+> =
+  arg => null;
diff --git a/tests/format/typescript/typeparams/empty-parameters-with-arrow-function/jsfmt.spec.js b/tests/format/typescript/typeparams/empty-parameters-with-arrow-function/jsfmt.spec.js
new file mode 100644
index 000000000000..4938c4f38220
--- /dev/null
+++ b/tests/format/typescript/typeparams/empty-parameters-with-arrow-function/jsfmt.spec.js
@@ -0,0 +1,6 @@
+run_spec(
+  __dirname,
+  ["typescript", "flow", "babel-flow"],
+  // #13817 require those options to reproduce
+  { arrowParens: "avoid", trailingComma: "all" }
+);