diff --git a/package.json b/package.json
index 97586c46d..7663ef39f 100644
--- a/package.json
+++ b/package.json
@@ -73,7 +73,7 @@
"fast-json-stable-stringify": "2.1.0",
"file-entry-cache": "11.1.3",
"find-cache-directory": "6.0.0",
- "flow-parser": "0.312.0",
+ "flow-parser": "0.314.0",
"get-east-asian-width": "1.6.0",
"get-stdin": "9.0.0",
"graphql": "16.14.0",
diff --git a/src/language-js/parentheses/needs-parentheses.js b/src/language-js/parentheses/needs-parentheses.js
index 3e4958682..971fc6f5b 100644
--- a/src/language-js/parentheses/needs-parentheses.js
+++ b/src/language-js/parentheses/needs-parentheses.js
@@ -380,12 +380,10 @@ function needsParentheses(path, options) {
(key === "constraint" &&
node.type === "TSConditionalType" &&
parent.type === "TSTypeParameter") ||
- (key === "typeAnnotation" &&
+ (key === "bound" &&
node.type === "ConditionalTypeAnnotation" &&
- parent.type === "TypeAnnotation" &&
- path.grandparent.type === "TypeParameter" &&
- path.grandparent.bound === parent &&
- path.grandparent.usesExtendsBound)
+ parent.type === "TypeParameter" &&
+ parent.usesExtendsBound)
) {
return true;
}
diff --git a/src/language-js/parse/postprocess/index.js b/src/language-js/parse/postprocess/index.js
index 226bb95eb..671a2fd94 100644
--- a/src/language-js/parse/postprocess/index.js
+++ b/src/language-js/parse/postprocess/index.js
@@ -181,6 +181,14 @@ function postprocess(ast, options) {
delete node.assertions;
}
break;
+
+ // Since flow@0.313.0, `TypeParameter.bound` is a bare type node without the `TypeAnnotation` wrapper
+ // https://github.com/facebook/flow/blob/HEAD/Changelog.md#03130
+ case "TypeParameter":
+ if (astType !== "flow" && node.bound?.type === "TypeAnnotation") {
+ node.bound = node.bound.typeAnnotation;
+ }
+ break;
}
},
onLeave(node) {
diff --git a/src/language-js/print/type-parameters.js b/src/language-js/print/type-parameters.js
index a2d74fc42..5cb0159ed 100644
--- a/src/language-js/print/type-parameters.js
+++ b/src/language-js/print/type-parameters.js
@@ -161,6 +161,8 @@ function printTypeParameter(path, options, print) {
if (node.bound) {
if (node.usesExtendsBound) {
parts.push(" extends ");
+ } else {
+ parts.push(": ");
}
parts.push(printTypeAnnotationProperty(path, print, "bound"));
diff --git a/tests/format/flow/type-parameters/flow-only/__snapshots__/format.test.js.snap b/tests/format/flow/type-parameters/flow-only/__snapshots__/format.test.js.snap
index f321a779a..2b0d18963 100644
--- a/tests/format/flow/type-parameters/flow-only/__snapshots__/format.test.js.snap
+++ b/tests/format/flow/type-parameters/flow-only/__snapshots__/format.test.js.snap
@@ -51,8 +51,8 @@ type A* comment */T :string> = B;
type A = B;
type A = B;
type A = B;
-type A = B;
-type A = B;
+type A = B;
+type A = B;
type A* comment */ T: string> = B;
================================================================================
diff --git a/yarn.lock b/yarn.lock
index f41db3fb5..2d472891b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5111,10 +5111,10 @@ __metadata:
languageName: node
linkType: hard
-"flow-parser@npm:0.312.0":
- version: 0.312.0
- resolution: "flow-parser@npm:0.312.0"
- checksum: 10/b6a7224a48ff456b18e49c1a5eba560a60bd754e014312096764b9d5394776119cc7bc9fe5f2fa19b0f87a9162683daad93f4c846a89c302733f80d7db3b9fcb
+"flow-parser@npm:0.314.0":
+ version: 0.314.0
+ resolution: "flow-parser@npm:0.314.0"
+ checksum: 10/4d494c3b8433b3076674a06b3b45ffb1c92e0d4d2e6c6f1f59033579d9ffa7bfc4f07982c0341da5b85431cc4bd5941550fbd6ca3a4c5be369909970eba3f7f9
languageName: node
linkType: hard
@@ -8282,7 +8282,7 @@ __metadata:
fast-json-stable-stringify: "npm:2.1.0"
file-entry-cache: "npm:11.1.3"
find-cache-directory: "npm:6.0.0"
- flow-parser: "npm:0.312.0"
+ flow-parser: "npm:0.314.0"
get-east-asian-width: "npm:1.6.0"
get-port: "npm:7.2.0"
get-stdin: "npm:9.0.0"