Repository: prettier/prettier (JavaScript)

Issue:
TS: Removal of necessary parentheses when using `infer U extends` syntax with multiple conditional checks
**Prettier 3.1.1**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEMCeAHOACAYhCAHgBUA+bAXm2OzgA94oATAZ2wAoBLKAMzgCdsAVVoMErbFACuAWwBGAgJTYAPtmDYAhkmzc+gkfUYTp8gdgC+2APzDsOqHABuAkABoQEDDE7QWyUE1+fggAdwAFIIR-FE0AG1DNNH8POX5NMABrOBgAZU0ZOAAZbjhkHniWOFT0rJzcjAzuAHNkGH4papAqmU42jq76LH5OQth44gEoIM44GIq4qo8WFri4AEUpCHhyyq6AKxY6XNWNrZ2kBaWQAEdzuHCQjBiQTRYAWkc4Jm-3VHTOHEWgBhCAyGSaZCvOJxP4rKDNNYAQRg7U4cik8HCAhKjl2iy6AAsYDI4gB1QmceAsRpgOC5aJUzhOKloKFgFgpEBOToASWYCDyYBG3iRzFy6DW+OuGBCVTJ6QwUNlcwELj+3Cq-Bgj00zQh0q6jX4Wqh6CwLGFnG8f1l3BgZM4TBghOQAA4AAwefhwO6cH26-WQy57DwwTRyR3O11IABMHikVWIEfmoZAcDMTB+TCKmgRUj1cHw-AhqJaUM0mIgIAsFiAA)
<!-- prettier-ignore -->
```sh
--parser typescript
```

**Input:**
<!-- prettier-ignore -->
```tsx
type Foo<T> = T extends (infer U extends number) | { a: infer U extends number } ? U : never
```

**Output:**
<!-- prettier-ignore -->
```tsx
type Foo<T> = T extends infer U extends number | { a: infer U extends number }
  ? U
  : never;

```

**Expected behavior:**
Same as input.  
Removal of the parentheses will break the code as the second condition gets treated as a part of union along with `number`, rather than a separate condition to be checked against.

[TS Playground](https://www.typescriptlang.org/play?ssl=3&ssc=91&pln=1&pc=1#code/C4TwDgpgBAYg9nAPAFQHxQLxWVCAPYCAOwBMBnKACgEsiAzCAJygFVcDjyoiBXAWwBGTAJRQAPlADeUAIYAuKLQbM2+QqQq9BTKAF8oAflZQFRCADcmAKCuhIUAEIzGKdFhxrOFJTtUcN3PxCzBLS8or0vuzqXFrBeobGphZMQA)


Hints:

Patch:
diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js
--- a/src/language-js/needs-parens.js
+++ b/src/language-js/needs-parens.js
@@ -567,8 +567,20 @@ function needsParens(path, options) {
       }
     // fallthrough
     case "TSInferType":
-      if (node.type === "TSInferType" && parent.type === "TSRestType") {
-        return false;
+      if (node.type === "TSInferType") {
+        if (parent.type === "TSRestType") {
+          return false;
+        }
+
+        if (
+          key === "types" &&
+          (parent.type === "TSUnionType" ||
+            parent.type === "TSIntersectionType") &&
+          node.typeParameter.type === "TSTypeParameter" &&
+          node.typeParameter.constraint
+        ) {
+          return true;
+        }
       }
     // fallthrough
     case "TSTypeOperator":


Test patch:
diff --git a/tests/format/typescript/infer-extends/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/infer-extends/__snapshots__/jsfmt.spec.js.snap
--- a/tests/format/typescript/infer-extends/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/typescript/infer-extends/__snapshots__/jsfmt.spec.js.snap
@@ -13,6 +13,8 @@ type X6<T> = T extends [infer U, infer U extends number] ? MustBeNumber<U> : nev
 type X7<T> = T extends [infer U extends string, infer U extends number] ? U : never;
 type X8<U, T> = T extends infer U extends number ? U : T;
 type X9<U, T> = T extends (infer U extends number ? U : T) ? U : T;
+type X10<T> = T extends (infer U extends number) | { a: infer U extends number } ? U : never
+type X11<T> = T extends (infer U extends number) & { a: infer U extends number } ? U : never
 
 =====================================output=====================================
 type X3<T> = T extends [infer U extends number] ? MustBeNumber<U> : never;
@@ -30,6 +32,12 @@ type X7<T> = T extends [infer U extends string, infer U extends number]
   : never;
 type X8<U, T> = T extends infer U extends number ? U : T;
 type X9<U, T> = T extends (infer U extends number ? U : T) ? U : T;
+type X10<T> = T extends (infer U extends number) | { a: infer U extends number }
+  ? U
+  : never;
+type X11<T> = T extends (infer U extends number) & { a: infer U extends number }
+  ? U
+  : never;
 
 ================================================================================
 `;
diff --git a/tests/format/typescript/infer-extends/basic.ts b/tests/format/typescript/infer-extends/basic.ts
--- a/tests/format/typescript/infer-extends/basic.ts
+++ b/tests/format/typescript/infer-extends/basic.ts
@@ -5,3 +5,5 @@ type X6<T> = T extends [infer U, infer U extends number] ? MustBeNumber<U> : nev
 type X7<T> = T extends [infer U extends string, infer U extends number] ? U : never;
 type X8<U, T> = T extends infer U extends number ? U : T;
 type X9<U, T> = T extends (infer U extends number ? U : T) ? U : T;
+type X10<T> = T extends (infer U extends number) | { a: infer U extends number } ? U : never
+type X11<T> = T extends (infer U extends number) & { a: infer U extends number } ? U : never