Repository: prettier/prettier (JavaScript)
Date: 2022-12-30 09:14:16+00:00
Task type: Feature

Issue:
Trailing commas for type parameters in Flow with --trailing-comma=es5
I'm not sure if this is the correct behavior or not, but I just moved from `trailingComma: "all"` to `trailingComma: "es5"` in our codebase at work, and was surprised to see these ones disappear.

**Prettier 1.9.2**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEMCeAHOACAYhCAFQAsBLAZwDkBDAWzgElyA1OAJzQBloBzAZSLFqMBjABCbONQDW5QoLiU4ADxidSUHAF5sA+jDJQeAHlyk25GAAVqbOgBpdcSFAAmNu7QB8AbhD2QCAwYUmhyZFBbNggAdw8EcJRqADcIUld-EGpLZBg2AFc4AIAjOzBpOBg+DGowDR5cgqKQVwgwZAAzagAbcmaNPrZrOx5aak6evoCAK3JlCVqKqro4dU0J3uaIfJgMHYAmDamQGot2ZBBi6mK0buhMjDYNGAB1dINkAA4ABgDHiD6LzsGAujzgg2ScEykgAjvlzHArCMxkdmn1aKRGoUAuR6t04ABFfIQeCogIwa5vVwfJD7cl2UjdeoAYQgtBRKHBAFZMvk+oRrokupsAL4ioA)
```sh
--trailing-comma es5
```

**Input:**
```jsx
type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<FirstParam, SecondParam>;
```

**Output:**
```jsx
type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<
  FirstParam,
  SecondParam
>;

```

**Prettier 1.9.2**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEMCeAHOACAYhCAFQAsBLAZwDkBDAWzgElyA1OAJzQBloBzAZSLFqMBjABCbONQDW5QoLiU4ADxidSUHAF5sA+jDJQeAHlyk25GAAVqbOgBpdcSFAAmNu7QB8AbhD2QCAwYUmhyZFBbNggAdw8EcJRqADcIUld-EGpLZBg2AFc4AIAjOzBpOBg+DGowDR5cgqKQVwgwZAAzagAbcmaNPrZrOx5aak6evoCAK3JlCVqKqro4dU0J3uaIfJgMHYAmDamQGot2ZBBi6mK0buhMjDYNGAB1dINkAA4ABgDHiD6LzsGAujzgg2ScEykgAjvlzHArCMxkdmn1aKRGoUAuR6t04ABFfIQeCogIwa5vVwfJD7cl2UjdeoAYQgtBRSW63Uy+T6hGuiS6mwAvsKgA)
```sh
--trailing-comma all
```

**Input:**
```jsx
type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<FirstParam, SecondParam>;
```

**Output:**
```jsx
type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<
  FirstParam,
  SecondParam,
>;

```

This affects both flow and typescript.

Seeing as type parameters aren't valid ES5 anyway, should we maybe include trailing commas there even when using `trailingComma: "es5"`?
Epic: Trailing commas in TS/Flow
This is an old problem and I thought I had an issue open to discuss this topic, but we should make a decision on this matter:

How do we handle trailing commas in different versions of Flow/TS?
Should we add `flowXXX` and `tsX.X` options?
Should we always support new trailing commas in `"all"` and treat `"es5"` as `"none"`?

cc @prettier/core


Issue discussion:
Related: https://github.com/prettier/prettier/issues/3662 https://github.com/prettier/prettier/pull/3313
Following that logic we could consider that `"es5" == "all"` since it's valid in TS anyway, not ES :joy: 
Yeah I guess that's kinda weird... I'm looking at it from the flow perspective, though.
@suchipi looks like an oversight to me. Feel free to fix it :)
From memory, older versions of TS don't support trailing commas here, I think it was intentional. Might want to double check
Issues raised on this topic: #6197 #3722 #3662 #3313
> Should we add flowXXX and tsX.X options?

I think yes, we planned same for php plugin, sometimes languages change syntax

> Should we always support new trailing commas in "all" and treat "es5" as "none"?

To avoid breaking code we should considered:
- `all` and `tsX.X`/`flowXXX` together (`all` + `ts3.3` !== `all` +`ts3.5` )
- with `none` no problems
- `es5` was bad idea, i don't know here solution, maybe apply trailing comma for lower level (i.e. apply commas only for lower ts/flow version like we use es5 and lower ts/flow version)
- https://github.com/prettier/plugin-php/issues/964#issuecomment-465558448
> - Personally, I think we should replace `--trailing-comma <none|es5|all>` with `--[no-]trailing-comma`/`--js-trailing-comma es5`, but unfortunately there's no backward-compatible way to do it in the CLI since string flags would suddenly become part of filenames.
> - PHP plugin: any option that wants to extend the existing one should have their own name, `--php-trailing-comma` for example. (Since we do support sub-language formatting (`embed`), it's not possible to use the same name with different option.)

- https://github.com/prettier/plugin-php/issues/964#issuecomment-465563804
> I meant the php-specific value (`php5`, `php7.2`) should have their own name (`--php-trailing-comma`) but the general value (`all`, `none`) can still be used as before (`--trailing-comma`). The `--php-trailing-comma` should take precedence over `--trailing-comma` in this plugin, something like:
> 
> ```ts
> function getPhpTrailingCommaValue(options): "all" | "php5" | "php7.2" | "none" {
>   if (options.phpTrailingComma) return options.phpTrailingComma;
>   if (options.trailingComma === "es5") return "none";
>   return options.trailingComma;
> }
> ```

Same thing can be applied to TS/Flow as well.
@ikatyang your solution sounds reasonable. I'll investigate that for 2.0
We can probably close this issue in favor of https://github.com/prettier/prettier/issues/11465
I just noticed #3722 is still open. Should that be included with Prettier 3?

Solution patch:
diff --git a/changelog_unreleased/flow/14085.md b/changelog_unreleased/flow/14085.md
new file mode 100644
index 000000000000..70f83764f5cd
--- /dev/null
+++ b/changelog_unreleased/flow/14085.md
@@ -0,0 +1,40 @@
+#### [BREAKING] Print trailing comma in type parameters and tuple types when `--trailing-comma=es5` (#14086, #14085 by @fisker)
+
+<!-- prettier-ignore -->
+```js
+// Input
+type Foo =  [
+  {
+    from: string,
+    to: string,
+  }, // <- 1
+];
+type Foo = Promise<
+  | { ok: true, bar: string, baz: SomeOtherLongType }
+  | { ok: false, bar: SomeOtherLongType }, // <- 2
+>;
+
+// Prettier stable
+type Foo = [
+  {
+    from: string,
+    to: string,
+  } // <- 1
+];
+type Foo = Promise<
+  | { ok: true, bar: string, baz: SomeOtherLongType }
+  | { ok: false, bar: SomeOtherLongType } // <- 2
+>;
+
+// Prettier main
+type Foo = [
+  {
+    from: string,
+    to: string,
+  }, // <- 1
+];
+type Foo = Promise<
+  | { ok: true, bar: string, baz: SomeOtherLongType }
+  | { ok: false, bar: SomeOtherLongType }, // <- 2
+>;
+```
diff --git a/src/language-js/print/type-parameters.js b/src/language-js/print/type-parameters.js
index 60a5df43f846..dd5b67242956 100644
--- a/src/language-js/print/type-parameters.js
+++ b/src/language-js/print/type-parameters.js
@@ -79,7 +79,7 @@ function printTypeParameters(path, options, print, paramsKey) {
         !node[paramsKey][0].constraint &&
         path.parent.type === "ArrowFunctionExpression"
       ? ","
-      : shouldPrintComma(options, "all")
+      : shouldPrintComma(options)
       ? ifBreak(",")
       : "";
 


Test patch:
diff --git a/tests/format/flow/function-parentheses/__snapshots__/jsfmt.spec.js.snap b/tests/format/flow/function-parentheses/__snapshots__/jsfmt.spec.js.snap
index 43344fd3b686..2c5515a4e049 100644
--- a/tests/format/flow/function-parentheses/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/flow/function-parentheses/__snapshots__/jsfmt.spec.js.snap
@@ -69,7 +69,7 @@ const selectorByPath:
 const selectorByPath: (Path) => SomethingSelector<
   SomethingUEditorContextType,
   SomethingUEditorContextType,
-  SomethingBulkValue<string>
+  SomethingBulkValue<string>,
 > = memoizeWithArgs(/* ... */);
 
 ================================================================================
diff --git a/tests/format/flow/generic/__snapshots__/jsfmt.spec.js.snap b/tests/format/flow/generic/__snapshots__/jsfmt.spec.js.snap
index 5aabf49c4856..8ffaa6ccef08 100644
--- a/tests/format/flow/generic/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/flow/generic/__snapshots__/jsfmt.spec.js.snap
@@ -63,7 +63,7 @@ var X = {
     E,
     F,
     G,
-    T: (a: A, b: B, c: C, d: D, e: E, f: F) => G // eslint-disable-line space-before-function-paren
+    T: (a: A, b: B, c: C, d: D, e: E, f: F) => G, // eslint-disable-line space-before-function-paren
   >(method: T, scope: any, a: A, b: B, c: C, d: D, e: E, f: F): G {},
 };
 
@@ -316,7 +316,7 @@ type State = {
 type State = {
   errors: Immutable.Map<
     Ahohohhohohohohohohohohohohooh,
-    Fbt | Immutable.Map<ErrorIndex, Fbt>
+    Fbt | Immutable.Map<ErrorIndex, Fbt>,
   >,
   shouldValidate: boolean,
 };
@@ -398,7 +398,7 @@ type Foo = Promise<
 =====================================output=====================================
 type Foo = Promise<
   | { ok: true, bar: string, baz: SomeOtherLongType }
-  | { ok: false, bar: SomeOtherLongType }
+  | { ok: false, bar: SomeOtherLongType },
 >;
 
 ================================================================================
diff --git a/tests/format/flow/interface-types/break/__snapshots__/jsfmt.spec.js.snap b/tests/format/flow/interface-types/break/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000000..d1a253553fd3
--- /dev/null
+++ b/tests/format/flow/interface-types/break/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,544 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`break.js - {"trailingComma":"all"} format 1`] = `
+====================================options=====================================
+parsers: ["flow"]
+printWidth: 80
+trailingComma: "all"
+                                                                                | printWidth
+=====================================input======================================
+export interface Environment1 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+> {
+  m(): void;
+};
+export class Environment2 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+  DifferentType1,
+  DifferentType2,
+  DifferentType3,
+  DifferentType4,
+> {
+  m() {};
+};
+
+// Declare Interface Break
+declare interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+declare interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+declare interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  x: string;
+}
+
+// Interface declaration break
+interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  s: string;
+}
+
+// Generic Types
+interface ExtendsOne extends ASingleInterface<string> {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
+  x: string;
+}
+
+interface ExtendsMany
+  extends ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7> {
+  x: string;
+}
+
+interface ExtendsManyWithGenerics
+  extends InterfaceOne, InterfaceTwo, ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7>, InterfaceThree {
+
+    x: string;
+  }
+
+export interface ExtendsLongOneWithGenerics extends Bar< SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,  ToBreakLineToBreakLineToBreakLine> {}
+
+=====================================output=====================================
+export interface Environment1
+  extends GenericEnvironment<SomeType, AnotherType, YetAnotherType> {
+  m(): void;
+}
+export class Environment2 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+  DifferentType1,
+  DifferentType2,
+  DifferentType3,
+  DifferentType4,
+> {
+  m() {}
+}
+
+// Declare Interface Break
+declare interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+declare interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+declare interface ExtendsMany
+  extends Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7 {
+  x: string;
+}
+
+// Interface declaration break
+interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+interface ExtendsMany
+  extends Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7 {
+  s: string;
+}
+
+// Generic Types
+interface ExtendsOne extends ASingleInterface<string> {
+  x: string;
+}
+
+interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
+  x: string;
+}
+
+interface ExtendsMany
+  extends ASingleGenericInterface<
+    Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7,
+  > {
+  x: string;
+}
+
+interface ExtendsManyWithGenerics
+  extends InterfaceOne,
+    InterfaceTwo,
+    ASingleGenericInterface<
+      Interface1,
+      Interface2,
+      Interface3,
+      Interface4,
+      Interface5,
+      Interface6,
+      Interface7,
+    >,
+    InterfaceThree {
+  x: string;
+}
+
+export interface ExtendsLongOneWithGenerics
+  extends Bar<
+    SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
+    ToBreakLineToBreakLineToBreakLine,
+  > {}
+
+================================================================================
+`;
+
+exports[`break.js - {"trailingComma":"es5"} format 1`] = `
+====================================options=====================================
+parsers: ["flow"]
+printWidth: 80
+trailingComma: "es5"
+                                                                                | printWidth
+=====================================input======================================
+export interface Environment1 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+> {
+  m(): void;
+};
+export class Environment2 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+  DifferentType1,
+  DifferentType2,
+  DifferentType3,
+  DifferentType4,
+> {
+  m() {};
+};
+
+// Declare Interface Break
+declare interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+declare interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+declare interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  x: string;
+}
+
+// Interface declaration break
+interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  s: string;
+}
+
+// Generic Types
+interface ExtendsOne extends ASingleInterface<string> {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
+  x: string;
+}
+
+interface ExtendsMany
+  extends ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7> {
+  x: string;
+}
+
+interface ExtendsManyWithGenerics
+  extends InterfaceOne, InterfaceTwo, ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7>, InterfaceThree {
+
+    x: string;
+  }
+
+export interface ExtendsLongOneWithGenerics extends Bar< SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,  ToBreakLineToBreakLineToBreakLine> {}
+
+=====================================output=====================================
+export interface Environment1
+  extends GenericEnvironment<SomeType, AnotherType, YetAnotherType> {
+  m(): void;
+}
+export class Environment2 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+  DifferentType1,
+  DifferentType2,
+  DifferentType3,
+  DifferentType4,
+> {
+  m() {}
+}
+
+// Declare Interface Break
+declare interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+declare interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+declare interface ExtendsMany
+  extends Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7 {
+  x: string;
+}
+
+// Interface declaration break
+interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+interface ExtendsMany
+  extends Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7 {
+  s: string;
+}
+
+// Generic Types
+interface ExtendsOne extends ASingleInterface<string> {
+  x: string;
+}
+
+interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
+  x: string;
+}
+
+interface ExtendsMany
+  extends ASingleGenericInterface<
+    Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7,
+  > {
+  x: string;
+}
+
+interface ExtendsManyWithGenerics
+  extends InterfaceOne,
+    InterfaceTwo,
+    ASingleGenericInterface<
+      Interface1,
+      Interface2,
+      Interface3,
+      Interface4,
+      Interface5,
+      Interface6,
+      Interface7,
+    >,
+    InterfaceThree {
+  x: string;
+}
+
+export interface ExtendsLongOneWithGenerics
+  extends Bar<
+    SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
+    ToBreakLineToBreakLineToBreakLine,
+  > {}
+
+================================================================================
+`;
+
+exports[`break.js - {"trailingComma":"none"} format 1`] = `
+====================================options=====================================
+parsers: ["flow"]
+printWidth: 80
+trailingComma: "none"
+                                                                                | printWidth
+=====================================input======================================
+export interface Environment1 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+> {
+  m(): void;
+};
+export class Environment2 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+  DifferentType1,
+  DifferentType2,
+  DifferentType3,
+  DifferentType4,
+> {
+  m() {};
+};
+
+// Declare Interface Break
+declare interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+declare interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+declare interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  x: string;
+}
+
+// Interface declaration break
+interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  s: string;
+}
+
+// Generic Types
+interface ExtendsOne extends ASingleInterface<string> {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
+  x: string;
+}
+
+interface ExtendsMany
+  extends ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7> {
+  x: string;
+}
+
+interface ExtendsManyWithGenerics
+  extends InterfaceOne, InterfaceTwo, ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7>, InterfaceThree {
+
+    x: string;
+  }
+
+export interface ExtendsLongOneWithGenerics extends Bar< SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,  ToBreakLineToBreakLineToBreakLine> {}
+
+=====================================output=====================================
+export interface Environment1
+  extends GenericEnvironment<SomeType, AnotherType, YetAnotherType> {
+  m(): void;
+}
+export class Environment2 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+  DifferentType1,
+  DifferentType2,
+  DifferentType3,
+  DifferentType4
+> {
+  m() {}
+}
+
+// Declare Interface Break
+declare interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+declare interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+declare interface ExtendsMany
+  extends Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7 {
+  x: string;
+}
+
+// Interface declaration break
+interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+interface ExtendsMany
+  extends Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7 {
+  s: string;
+}
+
+// Generic Types
+interface ExtendsOne extends ASingleInterface<string> {
+  x: string;
+}
+
+interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
+  x: string;
+}
+
+interface ExtendsMany
+  extends ASingleGenericInterface<
+    Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7
+  > {
+  x: string;
+}
+
+interface ExtendsManyWithGenerics
+  extends InterfaceOne,
+    InterfaceTwo,
+    ASingleGenericInterface<
+      Interface1,
+      Interface2,
+      Interface3,
+      Interface4,
+      Interface5,
+      Interface6,
+      Interface7
+    >,
+    InterfaceThree {
+  x: string;
+}
+
+export interface ExtendsLongOneWithGenerics
+  extends Bar<
+    SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
+    ToBreakLineToBreakLineToBreakLine
+  > {}
+
+================================================================================
+`;
diff --git a/tests/format/typescript/interface2/break.ts b/tests/format/flow/interface-types/break/break.js
similarity index 100%
rename from tests/format/typescript/interface2/break.ts
rename to tests/format/flow/interface-types/break/break.js
diff --git a/tests/format/flow/interface-types/break/jsfmt.spec.js b/tests/format/flow/interface-types/break/jsfmt.spec.js
new file mode 100644
index 000000000000..34c0a721b593
--- /dev/null
+++ b/tests/format/flow/interface-types/break/jsfmt.spec.js
@@ -0,0 +1,3 @@
+run_spec(import.meta, ["flow"], { trailingComma: "none" });
+run_spec(import.meta, ["flow"], { trailingComma: "es5" });
+run_spec(import.meta, ["flow"], { trailingComma: "all" });
diff --git a/tests/format/flow/type-parameters/trailing-comma/__snapshots__/jsfmt.spec.js.snap b/tests/format/flow/type-parameters/trailing-comma/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000000..64f97102f5d0
--- /dev/null
+++ b/tests/format/flow/type-parameters/trailing-comma/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,61 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`type-paramters.js - {"trailingComma":"all"} format 1`] = `
+====================================options=====================================
+parsers: ["flow"]
+printWidth: 80
+trailingComma: "all"
+                                                                                | printWidth
+=====================================input======================================
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<FirstParam, SecondParam>;
+type ShortName = Something<FirstParam, SecondParam>;
+
+=====================================output=====================================
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<
+  FirstParam,
+  SecondParam,
+>;
+type ShortName = Something<FirstParam, SecondParam>;
+
+================================================================================
+`;
+
+exports[`type-paramters.js - {"trailingComma":"es5"} format 1`] = `
+====================================options=====================================
+parsers: ["flow"]
+printWidth: 80
+trailingComma: "es5"
+                                                                                | printWidth
+=====================================input======================================
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<FirstParam, SecondParam>;
+type ShortName = Something<FirstParam, SecondParam>;
+
+=====================================output=====================================
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<
+  FirstParam,
+  SecondParam,
+>;
+type ShortName = Something<FirstParam, SecondParam>;
+
+================================================================================
+`;
+
+exports[`type-paramters.js - {"trailingComma":"none"} format 1`] = `
+====================================options=====================================
+parsers: ["flow"]
+printWidth: 80
+trailingComma: "none"
+                                                                                | printWidth
+=====================================input======================================
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<FirstParam, SecondParam>;
+type ShortName = Something<FirstParam, SecondParam>;
+
+=====================================output=====================================
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<
+  FirstParam,
+  SecondParam
+>;
+type ShortName = Something<FirstParam, SecondParam>;
+
+================================================================================
+`;
diff --git a/tests/format/flow/type-parameters/trailing-comma/jsfmt.spec.js b/tests/format/flow/type-parameters/trailing-comma/jsfmt.spec.js
new file mode 100644
index 000000000000..34c0a721b593
--- /dev/null
+++ b/tests/format/flow/type-parameters/trailing-comma/jsfmt.spec.js
@@ -0,0 +1,3 @@
+run_spec(import.meta, ["flow"], { trailingComma: "none" });
+run_spec(import.meta, ["flow"], { trailingComma: "es5" });
+run_spec(import.meta, ["flow"], { trailingComma: "all" });
diff --git a/tests/format/flow/type-parameters/trailing-comma/type-paramters.js b/tests/format/flow/type-parameters/trailing-comma/type-paramters.js
new file mode 100644
index 000000000000..4d2c96c92a53
--- /dev/null
+++ b/tests/format/flow/type-parameters/trailing-comma/type-paramters.js
@@ -0,0 +1,2 @@
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<FirstParam, SecondParam>;
+type ShortName = Something<FirstParam, SecondParam>;
diff --git a/tests/format/typescript/interface2/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/interface2/__snapshots__/jsfmt.spec.js.snap
index 3dd4f85911a6..965593b3a98a 100644
--- a/tests/format/typescript/interface2/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/typescript/interface2/__snapshots__/jsfmt.spec.js.snap
@@ -1,186 +1,5 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`break.ts - {"trailingComma":"es5"} format 1`] = `
-====================================options=====================================
-parsers: ["typescript", "flow"]
-printWidth: 80
-trailingComma: "es5"
-                                                                                | printWidth
-=====================================input======================================
-export interface Environment1 extends GenericEnvironment<
-  SomeType,
-  AnotherType,
-  YetAnotherType,
-> {
-  m(): void;
-};
-export class Environment2 extends GenericEnvironment<
-  SomeType,
-  AnotherType,
-  YetAnotherType,
-  DifferentType1,
-  DifferentType2,
-  DifferentType3,
-  DifferentType4,
-> {
-  m() {};
-};
-
-// Declare Interface Break
-declare interface ExtendsOne extends ASingleInterface {
-  x: string;
-}
-
-declare interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
-  x: string;
-}
-
-declare interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
-  x: string;
-}
-
-// Interface declaration break
-interface ExtendsOne extends ASingleInterface {
-  x: string;
-}
-
-interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
-  x: string;
-}
-
-interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
-  s: string;
-}
-
-// Generic Types
-interface ExtendsOne extends ASingleInterface<string> {
-  x: string;
-}
-
-interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
-  x: string;
-}
-
-interface ExtendsMany
-  extends ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7> {
-  x: string;
-}
-
-interface ExtendsManyWithGenerics
-  extends InterfaceOne, InterfaceTwo, ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7>, InterfaceThree {
-
-    x: string;
-  }
-
-export interface ExtendsLongOneWithGenerics extends Bar< SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,  ToBreakLineToBreakLineToBreakLine> {}
-
-=====================================output=====================================
-export interface Environment1
-  extends GenericEnvironment<SomeType, AnotherType, YetAnotherType> {
-  m(): void;
-}
-export class Environment2 extends GenericEnvironment<
-  SomeType,
-  AnotherType,
-  YetAnotherType,
-  DifferentType1,
-  DifferentType2,
-  DifferentType3,
-  DifferentType4
-> {
-  m() {}
-}
-
-// Declare Interface Break
-declare interface ExtendsOne extends ASingleInterface {
-  x: string;
-}
-
-declare interface ExtendsLarge
-  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
-  x: string;
-}
-
-declare interface ExtendsMany
-  extends Interface1,
-    Interface2,
-    Interface3,
-    Interface4,
-    Interface5,
-    Interface6,
-    Interface7 {
-  x: string;
-}
-
-// Interface declaration break
-interface ExtendsOne extends ASingleInterface {
-  x: string;
-}
-
-interface ExtendsLarge
-  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
-  x: string;
-}
-
-interface ExtendsMany
-  extends Interface1,
-    Interface2,
-    Interface3,
-    Interface4,
-    Interface5,
-    Interface6,
-    Interface7 {
-  s: string;
-}
-
-// Generic Types
-interface ExtendsOne extends ASingleInterface<string> {
-  x: string;
-}
-
-interface ExtendsLarge
-  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
-  x: string;
-}
-
-interface ExtendsMany
-  extends ASingleGenericInterface<
-    Interface1,
-    Interface2,
-    Interface3,
-    Interface4,
-    Interface5,
-    Interface6,
-    Interface7
-  > {
-  x: string;
-}
-
-interface ExtendsManyWithGenerics
-  extends InterfaceOne,
-    InterfaceTwo,
-    ASingleGenericInterface<
-      Interface1,
-      Interface2,
-      Interface3,
-      Interface4,
-      Interface5,
-      Interface6,
-      Interface7
-    >,
-    InterfaceThree {
-  x: string;
-}
-
-export interface ExtendsLongOneWithGenerics
-  extends Bar<
-    SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
-    ToBreakLineToBreakLineToBreakLine
-  > {}
-
-================================================================================
-`;
-
 exports[`comments.ts - {"trailingComma":"es5"} format 1`] = `
 ====================================options=====================================
 parsers: ["typescript", "flow"]
diff --git a/tests/format/typescript/interface2/break/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/interface2/break/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000000..38e0de3d9d47
--- /dev/null
+++ b/tests/format/typescript/interface2/break/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,544 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`break.ts - {"trailingComma":"all"} format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+trailingComma: "all"
+                                                                                | printWidth
+=====================================input======================================
+export interface Environment1 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+> {
+  m(): void;
+};
+export class Environment2 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+  DifferentType1,
+  DifferentType2,
+  DifferentType3,
+  DifferentType4,
+> {
+  m() {};
+};
+
+// Declare Interface Break
+declare interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+declare interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+declare interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  x: string;
+}
+
+// Interface declaration break
+interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  s: string;
+}
+
+// Generic Types
+interface ExtendsOne extends ASingleInterface<string> {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
+  x: string;
+}
+
+interface ExtendsMany
+  extends ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7> {
+  x: string;
+}
+
+interface ExtendsManyWithGenerics
+  extends InterfaceOne, InterfaceTwo, ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7>, InterfaceThree {
+
+    x: string;
+  }
+
+export interface ExtendsLongOneWithGenerics extends Bar< SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,  ToBreakLineToBreakLineToBreakLine> {}
+
+=====================================output=====================================
+export interface Environment1
+  extends GenericEnvironment<SomeType, AnotherType, YetAnotherType> {
+  m(): void;
+}
+export class Environment2 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+  DifferentType1,
+  DifferentType2,
+  DifferentType3,
+  DifferentType4
+> {
+  m() {}
+}
+
+// Declare Interface Break
+declare interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+declare interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+declare interface ExtendsMany
+  extends Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7 {
+  x: string;
+}
+
+// Interface declaration break
+interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+interface ExtendsMany
+  extends Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7 {
+  s: string;
+}
+
+// Generic Types
+interface ExtendsOne extends ASingleInterface<string> {
+  x: string;
+}
+
+interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
+  x: string;
+}
+
+interface ExtendsMany
+  extends ASingleGenericInterface<
+    Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7
+  > {
+  x: string;
+}
+
+interface ExtendsManyWithGenerics
+  extends InterfaceOne,
+    InterfaceTwo,
+    ASingleGenericInterface<
+      Interface1,
+      Interface2,
+      Interface3,
+      Interface4,
+      Interface5,
+      Interface6,
+      Interface7
+    >,
+    InterfaceThree {
+  x: string;
+}
+
+export interface ExtendsLongOneWithGenerics
+  extends Bar<
+    SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
+    ToBreakLineToBreakLineToBreakLine
+  > {}
+
+================================================================================
+`;
+
+exports[`break.ts - {"trailingComma":"es5"} format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+trailingComma: "es5"
+                                                                                | printWidth
+=====================================input======================================
+export interface Environment1 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+> {
+  m(): void;
+};
+export class Environment2 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+  DifferentType1,
+  DifferentType2,
+  DifferentType3,
+  DifferentType4,
+> {
+  m() {};
+};
+
+// Declare Interface Break
+declare interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+declare interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+declare interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  x: string;
+}
+
+// Interface declaration break
+interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  s: string;
+}
+
+// Generic Types
+interface ExtendsOne extends ASingleInterface<string> {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
+  x: string;
+}
+
+interface ExtendsMany
+  extends ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7> {
+  x: string;
+}
+
+interface ExtendsManyWithGenerics
+  extends InterfaceOne, InterfaceTwo, ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7>, InterfaceThree {
+
+    x: string;
+  }
+
+export interface ExtendsLongOneWithGenerics extends Bar< SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,  ToBreakLineToBreakLineToBreakLine> {}
+
+=====================================output=====================================
+export interface Environment1
+  extends GenericEnvironment<SomeType, AnotherType, YetAnotherType> {
+  m(): void;
+}
+export class Environment2 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+  DifferentType1,
+  DifferentType2,
+  DifferentType3,
+  DifferentType4
+> {
+  m() {}
+}
+
+// Declare Interface Break
+declare interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+declare interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+declare interface ExtendsMany
+  extends Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7 {
+  x: string;
+}
+
+// Interface declaration break
+interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+interface ExtendsMany
+  extends Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7 {
+  s: string;
+}
+
+// Generic Types
+interface ExtendsOne extends ASingleInterface<string> {
+  x: string;
+}
+
+interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
+  x: string;
+}
+
+interface ExtendsMany
+  extends ASingleGenericInterface<
+    Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7
+  > {
+  x: string;
+}
+
+interface ExtendsManyWithGenerics
+  extends InterfaceOne,
+    InterfaceTwo,
+    ASingleGenericInterface<
+      Interface1,
+      Interface2,
+      Interface3,
+      Interface4,
+      Interface5,
+      Interface6,
+      Interface7
+    >,
+    InterfaceThree {
+  x: string;
+}
+
+export interface ExtendsLongOneWithGenerics
+  extends Bar<
+    SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
+    ToBreakLineToBreakLineToBreakLine
+  > {}
+
+================================================================================
+`;
+
+exports[`break.ts - {"trailingComma":"none"} format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+trailingComma: "none"
+                                                                                | printWidth
+=====================================input======================================
+export interface Environment1 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+> {
+  m(): void;
+};
+export class Environment2 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+  DifferentType1,
+  DifferentType2,
+  DifferentType3,
+  DifferentType4,
+> {
+  m() {};
+};
+
+// Declare Interface Break
+declare interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+declare interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+declare interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  x: string;
+}
+
+// Interface declaration break
+interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  s: string;
+}
+
+// Generic Types
+interface ExtendsOne extends ASingleInterface<string> {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
+  x: string;
+}
+
+interface ExtendsMany
+  extends ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7> {
+  x: string;
+}
+
+interface ExtendsManyWithGenerics
+  extends InterfaceOne, InterfaceTwo, ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7>, InterfaceThree {
+
+    x: string;
+  }
+
+export interface ExtendsLongOneWithGenerics extends Bar< SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,  ToBreakLineToBreakLineToBreakLine> {}
+
+=====================================output=====================================
+export interface Environment1
+  extends GenericEnvironment<SomeType, AnotherType, YetAnotherType> {
+  m(): void;
+}
+export class Environment2 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+  DifferentType1,
+  DifferentType2,
+  DifferentType3,
+  DifferentType4
+> {
+  m() {}
+}
+
+// Declare Interface Break
+declare interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+declare interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+declare interface ExtendsMany
+  extends Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7 {
+  x: string;
+}
+
+// Interface declaration break
+interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+interface ExtendsMany
+  extends Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7 {
+  s: string;
+}
+
+// Generic Types
+interface ExtendsOne extends ASingleInterface<string> {
+  x: string;
+}
+
+interface ExtendsLarge
+  extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
+  x: string;
+}
+
+interface ExtendsMany
+  extends ASingleGenericInterface<
+    Interface1,
+    Interface2,
+    Interface3,
+    Interface4,
+    Interface5,
+    Interface6,
+    Interface7
+  > {
+  x: string;
+}
+
+interface ExtendsManyWithGenerics
+  extends InterfaceOne,
+    InterfaceTwo,
+    ASingleGenericInterface<
+      Interface1,
+      Interface2,
+      Interface3,
+      Interface4,
+      Interface5,
+      Interface6,
+      Interface7
+    >,
+    InterfaceThree {
+  x: string;
+}
+
+export interface ExtendsLongOneWithGenerics
+  extends Bar<
+    SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,
+    ToBreakLineToBreakLineToBreakLine
+  > {}
+
+================================================================================
+`;
diff --git a/tests/format/typescript/interface2/break/break.ts b/tests/format/typescript/interface2/break/break.ts
new file mode 100644
index 000000000000..3bf95b1df837
--- /dev/null
+++ b/tests/format/typescript/interface2/break/break.ts
@@ -0,0 +1,66 @@
+export interface Environment1 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+> {
+  m(): void;
+};
+export class Environment2 extends GenericEnvironment<
+  SomeType,
+  AnotherType,
+  YetAnotherType,
+  DifferentType1,
+  DifferentType2,
+  DifferentType3,
+  DifferentType4,
+> {
+  m() {};
+};
+
+// Declare Interface Break
+declare interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+declare interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+declare interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  x: string;
+}
+
+// Interface declaration break
+interface ExtendsOne extends ASingleInterface {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName {
+  x: string;
+}
+
+interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
+  s: string;
+}
+
+// Generic Types
+interface ExtendsOne extends ASingleInterface<string> {
+  x: string;
+}
+
+interface ExtendsLarge extends ASingleInterfaceWithAReallyReallyReallyReallyLongName<string> {
+  x: string;
+}
+
+interface ExtendsMany
+  extends ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7> {
+  x: string;
+}
+
+interface ExtendsManyWithGenerics
+  extends InterfaceOne, InterfaceTwo, ASingleGenericInterface<Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7>, InterfaceThree {
+
+    x: string;
+  }
+
+export interface ExtendsLongOneWithGenerics extends Bar< SomeLongTypeSomeLongTypeSomeLongTypeSomeLongType,  ToBreakLineToBreakLineToBreakLine> {}
diff --git a/tests/format/typescript/interface2/break/jsfmt.spec.js b/tests/format/typescript/interface2/break/jsfmt.spec.js
new file mode 100644
index 000000000000..becf57ccb99e
--- /dev/null
+++ b/tests/format/typescript/interface2/break/jsfmt.spec.js
@@ -0,0 +1,3 @@
+run_spec(import.meta, ["typescript"], { trailingComma: "none" });
+run_spec(import.meta, ["typescript"], { trailingComma: "es5" });
+run_spec(import.meta, ["typescript"], { trailingComma: "all" });
diff --git a/tests/format/typescript/trailing-comma/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/trailing-comma/__snapshots__/jsfmt.spec.js.snap
index 8651c7ad2746..ee42b39c778f 100644
--- a/tests/format/typescript/trailing-comma/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/typescript/trailing-comma/__snapshots__/jsfmt.spec.js.snap
@@ -133,7 +133,7 @@ const {
 
 =====================================output=====================================
 export class BaseSingleLevelProfileTargeting<
-  T extends ValidSingleLevelProfileNode
+  T extends ValidSingleLevelProfileNode,
 > {}
 
 enum Enum {
diff --git a/tests/format/typescript/typeparams/trailing-comma/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/typeparams/trailing-comma/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000000..a2f4e64c876b
--- /dev/null
+++ b/tests/format/typescript/typeparams/trailing-comma/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,61 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`type-paramters.ts - {"trailingComma":"all"} format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+trailingComma: "all"
+                                                                                | printWidth
+=====================================input======================================
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<FirstParam, SecondParam>;
+type ShortName = Something<FirstParam, SecondParam>;
+
+=====================================output=====================================
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<
+  FirstParam,
+  SecondParam
+>;
+type ShortName = Something<FirstParam, SecondParam>;
+
+================================================================================
+`;
+
+exports[`type-paramters.ts - {"trailingComma":"es5"} format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+trailingComma: "es5"
+                                                                                | printWidth
+=====================================input======================================
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<FirstParam, SecondParam>;
+type ShortName = Something<FirstParam, SecondParam>;
+
+=====================================output=====================================
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<
+  FirstParam,
+  SecondParam
+>;
+type ShortName = Something<FirstParam, SecondParam>;
+
+================================================================================
+`;
+
+exports[`type-paramters.ts - {"trailingComma":"none"} format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+trailingComma: "none"
+                                                                                | printWidth
+=====================================input======================================
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<FirstParam, SecondParam>;
+type ShortName = Something<FirstParam, SecondParam>;
+
+=====================================output=====================================
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<
+  FirstParam,
+  SecondParam
+>;
+type ShortName = Something<FirstParam, SecondParam>;
+
+================================================================================
+`;
diff --git a/tests/format/typescript/typeparams/trailing-comma/jsfmt.spec.js b/tests/format/typescript/typeparams/trailing-comma/jsfmt.spec.js
new file mode 100644
index 000000000000..becf57ccb99e
--- /dev/null
+++ b/tests/format/typescript/typeparams/trailing-comma/jsfmt.spec.js
@@ -0,0 +1,3 @@
+run_spec(import.meta, ["typescript"], { trailingComma: "none" });
+run_spec(import.meta, ["typescript"], { trailingComma: "es5" });
+run_spec(import.meta, ["typescript"], { trailingComma: "all" });
diff --git a/tests/format/typescript/typeparams/trailing-comma/type-paramters.ts b/tests/format/typescript/typeparams/trailing-comma/type-paramters.ts
new file mode 100644
index 000000000000..4d2c96c92a53
--- /dev/null
+++ b/tests/format/typescript/typeparams/trailing-comma/type-paramters.ts
@@ -0,0 +1,2 @@
+type FooThisNameIsVeryLongSoThatItBreaksToTheNextLine = Something<FirstParam, SecondParam>;
+type ShortName = Something<FirstParam, SecondParam>;