diff --git a/changelog_unreleased/typescript/10109.md b/changelog_unreleased/typescript/10109.md
index 1a54cb3b3..e1bbb5aa5 100644
--- a/changelog_unreleased/typescript/10109.md
+++ b/changelog_unreleased/typescript/10109.md
@@ -1,43 +1,29 @@
-#### Print trailing commas for TS type parameters (#10109 by @sosukesuzuki)
+#### Print trailing commas in type parameters (#10109 by @sosukesuzuki, #10353 by @thorn0)
-Initially, Prettier printed trailing commas in TypeScript type parameters with `--trailing-comma=all`, but TypeScript did not support it at the time, so the feature was removed. However, it is supported now (since TypeScript 2.7 released in January 2018).
+TypeScript has been supporting trailing commas in type parameters since TypeScript 2.7 released in January 2018. Prettier main prints them if the `trailingComma` option is set to `all`. Keep this option at the more conservative default value `es5` if compatibility with TypeScript 2.7 or older is needed. Note that TypeScript [still doesn't support][ts-issue-21984] trailing commas in type arguments (type parameter instantiations).
+
+[ts-issue-21984]: https://github.com/microsoft/TypeScript/issues/21984
```ts
// Input
-var bar: Bar<
- AAAAAAA,
- BBBBBBB,
- CCCCCCC,
- DDDDDDD,
- EEEEEEE,
- FFFFFFF,
- GGGGGGG,
- HHHHHHH
->;
+export class BaseSingleLevelProfileTargeting<
+ T extends ValidSingleLevelProfileNode,
+> {
+ // ...
+}
// Prettier stable
-var bar: Bar<
- AAAAAAA,
- BBBBBBB,
- CCCCCCC,
- DDDDDDD,
- EEEEEEE,
- FFFFFFF,
- GGGGGGG,
- HHHHHHH
->;
-
-// Prettier main
-var bar: Bar<
- AAAAAAA,
- BBBBBBB,
- CCCCCCC,
- DDDDDDD,
- EEEEEEE,
- FFFFFFF,
- GGGGGGG,
- HHHHHHH,
->;
+export class BaseSingleLevelProfileTargeting<
+ T extends ValidSingleLevelProfileNode
+> {
+ // ...
+}
+// Prettier main with --trailling-comma=all
+export class BaseSingleLevelProfileTargeting<
+ T extends ValidSingleLevelProfileNode,
+> {
+ // ...
+}
```
diff --git a/docs/options.md b/docs/options.md
index caf6f5024..243c041ff 100644
--- a/docs/options.md
+++ b/docs/options.md
@@ -110,13 +110,13 @@ Use single quotes instead of double quotes in JSX.
_Default value changed from `none` to `es5` in v2.0.0_
-Print trailing commas wherever possible when multi-line. (A single-line array, for example, never gets trailing commas.)
+Print trailing commas wherever possible in multi-line comma-separated syntactic structures. (A single-line array, for example, never gets trailing commas.)
Valid options:
-- `"es5"` - Trailing commas where valid in ES5 (objects, arrays, etc.)
+- `"es5"` - Trailing commas where valid in ES5 (objects, arrays, etc.). No trailing commas in type parameters in TypeScript.
- `"none"` - No trailing commas.
-- `"all"` - Trailing commas wherever possible (including [trailing commas in function parameter lists and calls](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Trailing_commas#Trailing_commas_in_functions)). This requires node 8 or a modern browser that supports ES2017 or transform with [babel](https://babeljs.io/docs/en/index).
+- `"all"` - Trailing commas wherever possible (including [function parameters and calls](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Trailing_commas#Trailing_commas_in_functions)). To run, JavaScript code formatted this way needs an engine that supports ES2017 (Node.js 8+ or a modern browser) or [downlevel compilation](https://babeljs.io/docs/en/index). This also enables trailing commas in type parameters in TypeScript (supported since TypeScript 2.7 released in January 2018).
| Default | CLI Override | API Override |
| ------- | ------------------------------------------------------ | ------------------------------------------------------ |
diff --git a/src/language-js/print/type-parameters.js b/src/language-js/print/type-parameters.js
index a747967fd..3c00e1135 100644
--- a/src/language-js/print/type-parameters.js
+++ b/src/language-js/print/type-parameters.js
@@ -56,10 +56,12 @@ function printTypeParameters(path, options, print, paramsKey) {
// has one type parameter that isn't extend with any types.
// Because, otherwise formatted result will be invalid as tsx.
const trailingComma =
- getFunctionParameters(n).length === 1 &&
- isTSXFile(options) &&
- !n[paramsKey][0].constraint &&
- path.getParentNode().type === "ArrowFunctionExpression"
+ n.type === "TSTypeParameterInstantiation" // https://github.com/microsoft/TypeScript/issues/21984
+ ? ""
+ : getFunctionParameters(n).length === 1 &&
+ isTSXFile(options) &&
+ !n[paramsKey][0].constraint &&
+ path.getParentNode().type === "ArrowFunctionExpression"
? ","
: shouldPrintComma(options, "all")
? ifBreak(",")
diff --git a/tests/typescript/trailing-comma/__snapshots__/jsfmt.spec.js.snap b/tests/typescript/trailing-comma/__snapshots__/jsfmt.spec.js.snap
index 3fe0b32a0..8651c7ad2 100644
--- a/tests/typescript/trailing-comma/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/typescript/trailing-comma/__snapshots__/jsfmt.spec.js.snap
@@ -195,7 +195,7 @@ const {
================================================================================
`;
-exports[`type-parameters.ts - {"trailingComma":"all"} format 1`] = `
+exports[`type-arguments.ts - {"trailingComma":"all"} format 1`] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
@@ -213,6 +213,11 @@ var bar: Bar<
HHHHHHH
>;
+const baz = new Array<
+ FooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo,
+ BarBarBarBarBarBarBarBarBarBarBarBarBarBarBar
+>();
+
=====================================output=====================================
var bar: Bar<
AAAAAAA,
@@ -222,13 +227,18 @@ var bar: Bar<
EEEEEEE,
FFFFFFF,
GGGGGGG,
- HHHHHHH,
+ HHHHHHH
>;
+const baz = new Array<
+ FooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo,
+ BarBarBarBarBarBarBarBarBarBarBarBarBarBarBar
+>();
+
================================================================================
`;
-exports[`type-parameters.ts - {"trailingComma":"es5"} format 1`] = `
+exports[`type-arguments.ts - {"trailingComma":"es5"} format 1`] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
@@ -246,6 +256,11 @@ var bar: Bar<
HHHHHHH
>;
+const baz = new Array<
+ FooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo,
+ BarBarBarBarBarBarBarBarBarBarBarBarBarBarBar
+>();
+
=====================================output=====================================
var bar: Bar<
AAAAAAA,
@@ -258,10 +273,15 @@ var bar: Bar<
HHHHHHH
>;
+const baz = new Array<
+ FooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo,
+ BarBarBarBarBarBarBarBarBarBarBarBarBarBarBar
+>();
+
================================================================================
`;
-exports[`type-parameters.ts - {"trailingComma":"none"} format 1`] = `
+exports[`type-arguments.ts - {"trailingComma":"none"} format 1`] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
@@ -279,6 +299,11 @@ var bar: Bar<
HHHHHHH
>;
+const baz = new Array<
+ FooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo,
+ BarBarBarBarBarBarBarBarBarBarBarBarBarBarBar
+>();
+
=====================================output=====================================
var bar: Bar<
AAAAAAA,
@@ -291,5 +316,127 @@ var bar: Bar<
HHHHHHH
>;
+const baz = new Array<
+ FooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo,
+ BarBarBarBarBarBarBarBarBarBarBarBarBarBarBar
+>();
+
+================================================================================
+`;
+
+exports[`type-parameters-vs-arguments.ts - {"trailingComma":"all"} format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+trailingComma: "all"
+ | printWidth
+=====================================input======================================
+class FooClass<
+ A,
+ B,
+ C,
+> {
+ a: A;
+ b: B;
+ c: C;
+}
+
+const instance = new FooClass<
+ boolean,
+ number,
+ string, // [ts] Trailing comma not allowed.
+ >();
+
+=====================================output=====================================
+class FooClass {
+ a: A;
+ b: B;
+ c: C;
+}
+
+const instance = new FooClass<
+ boolean,
+ number,
+ string // [ts] Trailing comma not allowed.
+>();
+
+================================================================================
+`;
+
+exports[`type-parameters-vs-arguments.ts - {"trailingComma":"es5"} format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+trailingComma: "es5"
+ | printWidth
+=====================================input======================================
+class FooClass<
+ A,
+ B,
+ C,
+> {
+ a: A;
+ b: B;
+ c: C;
+}
+
+const instance = new FooClass<
+ boolean,
+ number,
+ string, // [ts] Trailing comma not allowed.
+ >();
+
+=====================================output=====================================
+class FooClass {
+ a: A;
+ b: B;
+ c: C;
+}
+
+const instance = new FooClass<
+ boolean,
+ number,
+ string // [ts] Trailing comma not allowed.
+>();
+
+================================================================================
+`;
+
+exports[`type-parameters-vs-arguments.ts - {"trailingComma":"none"} format 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+trailingComma: "none"
+ | printWidth
+=====================================input======================================
+class FooClass<
+ A,
+ B,
+ C,
+> {
+ a: A;
+ b: B;
+ c: C;
+}
+
+const instance = new FooClass<
+ boolean,
+ number,
+ string, // [ts] Trailing comma not allowed.
+ >();
+
+=====================================output=====================================
+class FooClass {
+ a: A;
+ b: B;
+ c: C;
+}
+
+const instance = new FooClass<
+ boolean,
+ number,
+ string // [ts] Trailing comma not allowed.
+>();
+
================================================================================
`;
diff --git a/tests/typescript/trailing-comma/type-arguments.ts b/tests/typescript/trailing-comma/type-arguments.ts
new file mode 100644
index 000000000..84a9e915d
--- /dev/null
+++ b/tests/typescript/trailing-comma/type-arguments.ts
@@ -0,0 +1,15 @@
+var bar: Bar<
+ AAAAAAA,
+ BBBBBBB,
+ CCCCCCC,
+ DDDDDDD,
+ EEEEEEE,
+ FFFFFFF,
+ GGGGGGG,
+ HHHHHHH
+>;
+
+const baz = new Array<
+ FooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo,
+ BarBarBarBarBarBarBarBarBarBarBarBarBarBarBar
+>();
diff --git a/tests/typescript/trailing-comma/type-parameters-vs-arguments.ts b/tests/typescript/trailing-comma/type-parameters-vs-arguments.ts
new file mode 100644
index 000000000..8d5ac46d6
--- /dev/null
+++ b/tests/typescript/trailing-comma/type-parameters-vs-arguments.ts
@@ -0,0 +1,15 @@
+class FooClass<
+ A,
+ B,
+ C,
+> {
+ a: A;
+ b: B;
+ c: C;
+}
+
+const instance = new FooClass<
+ boolean,
+ number,
+ string, // [ts] Trailing comma not allowed.
+ >();
diff --git a/tests/typescript/trailing-comma/type-parameters.ts b/tests/typescript/trailing-comma/type-parameters.ts
deleted file mode 100644
index 058c607a1..000000000
--- a/tests/typescript/trailing-comma/type-parameters.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-var bar: Bar<
- AAAAAAA,
- BBBBBBB,
- CCCCCCC,
- DDDDDDD,
- EEEEEEE,
- FFFFFFF,
- GGGGGGG,
- HHHHHHH
->;