diff --git a/changelog_unreleased/flow/17792.md b/changelog_unreleased/flow/17792.md new file mode 100644 index 000000000..5be03aee4 --- /dev/null +++ b/changelog_unreleased/flow/17792.md @@ -0,0 +1,19 @@ +#### Add support for opaque type with lower and upper bound (#17792 by @SamChou19815) + + +```jsx +// Input +opaque type Counter super empty extends Box = Container; +opaque type Counter super Box = Container; +declare opaque type Counter super empty extends Box; +declare opaque type Counter super Box; + +// Prettier stable +SyntaxError: Unexpected identifier, expected the token `=` (1:21) + +// Prettier main +opaque type Counter super empty extends Box = Container; +opaque type Counter super Box = Container; +declare opaque type Counter super empty extends Box; +declare opaque type Counter super Box; +``` diff --git a/src/language-js/print/type-annotation.js b/src/language-js/print/type-annotation.js index f53943c6e..915047e30 100644 --- a/src/language-js/print/type-annotation.js +++ b/src/language-js/print/type-annotation.js @@ -95,6 +95,21 @@ function printOpaqueType(path, options, print) { parts.push(": ", print("supertype")); } + if (node.lowerBound || node.upperBound) { + const lowerAndUpperBoundParts = []; + if (node.lowerBound) { + lowerAndUpperBoundParts.push( + indent([line, "super ", print("lowerBound")]), + ); + } + if (node.upperBound) { + lowerAndUpperBoundParts.push( + indent([line, "extends ", print("upperBound")]), + ); + } + parts.push(group(lowerAndUpperBoundParts)); + } + if (node.impltype) { parts.push(" = ", print("impltype")); } diff --git a/src/language-js/traverse/visitor-keys.evaluate.js b/src/language-js/traverse/visitor-keys.evaluate.js index b727f69ed..5f32e0c9c 100644 --- a/src/language-js/traverse/visitor-keys.evaluate.js +++ b/src/language-js/traverse/visitor-keys.evaluate.js @@ -46,8 +46,7 @@ const excludeKeys = { PropertyDefinition: ["tsModifiers"], // Not supported yet. // https://github.com/facebook/hermes/commit/55a5f881361ef15fd4f7b558166d80e7b9086550 - DeclareOpaqueType: ["impltype", "lowerBound", "upperBound"], - OpaqueType: ["lowerBound", "upperBound"], + DeclareOpaqueType: ["impltype"], // Legacy property ExportAllDeclaration: ["assertions"], diff --git a/tests/format/flow/type-declarations/__snapshots__/format.test.js.snap b/tests/format/flow/type-declarations/__snapshots__/format.test.js.snap index 29080a080..3ec272e15 100644 --- a/tests/format/flow/type-declarations/__snapshots__/format.test.js.snap +++ b/tests/format/flow/type-declarations/__snapshots__/format.test.js.snap @@ -258,6 +258,17 @@ opaque type overloads = & ((x: string) => number) & ((x: number) => string); +opaque type Counter super empty extends Box = Container; +opaque type Counter super Box = Container; + +opaque type Counter super Looooooooooooooooooog extends BoxLooooooooooooooooooog = Container; +opaque type Counter super BoxLooooooooooooooooooooooooooooooooog = Container; + +declare opaque type Counter super empty extends Box; +declare opaque type Counter super Box; +declare opaque type Counter super Looooooooooooooooooog extends BoxLooooooooooooooooooog; +declare opaque type Counter super BoxLooooooooooooooooooooooooooooooooooooooooooooooog; + =====================================output===================================== declare export opaque type Foo declare export opaque type Bar @@ -272,6 +283,23 @@ export opaque type Foo5 = number opaque type union = { type: "A" } | { type: "B" } opaque type overloads = ((x: string) => number) & ((x: number) => string) +opaque type Counter super empty extends Box = Container +opaque type Counter super Box = Container + +opaque type Counter + super Looooooooooooooooooog + extends BoxLooooooooooooooooooog = Container +opaque type Counter + super BoxLooooooooooooooooooooooooooooooooog = Container + +declare opaque type Counter super empty extends Box +declare opaque type Counter super Box +declare opaque type Counter + super Looooooooooooooooooog + extends BoxLooooooooooooooooooog +declare opaque type Counter + super BoxLooooooooooooooooooooooooooooooooooooooooooooooog + ================================================================================ `; @@ -298,6 +326,17 @@ opaque type overloads = & ((x: string) => number) & ((x: number) => string); +opaque type Counter super empty extends Box = Container; +opaque type Counter super Box = Container; + +opaque type Counter super Looooooooooooooooooog extends BoxLooooooooooooooooooog = Container; +opaque type Counter super BoxLooooooooooooooooooooooooooooooooog = Container; + +declare opaque type Counter super empty extends Box; +declare opaque type Counter super Box; +declare opaque type Counter super Looooooooooooooooooog extends BoxLooooooooooooooooooog; +declare opaque type Counter super BoxLooooooooooooooooooooooooooooooooooooooooooooooog; + =====================================output===================================== declare export opaque type Foo; declare export opaque type Bar; @@ -312,5 +351,22 @@ export opaque type Foo5 = number; opaque type union = { type: "A" } | { type: "B" }; opaque type overloads = ((x: string) => number) & ((x: number) => string); +opaque type Counter super empty extends Box = Container; +opaque type Counter super Box = Container; + +opaque type Counter + super Looooooooooooooooooog + extends BoxLooooooooooooooooooog = Container; +opaque type Counter + super BoxLooooooooooooooooooooooooooooooooog = Container; + +declare opaque type Counter super empty extends Box; +declare opaque type Counter super Box; +declare opaque type Counter + super Looooooooooooooooooog + extends BoxLooooooooooooooooooog; +declare opaque type Counter + super BoxLooooooooooooooooooooooooooooooooooooooooooooooog; + ================================================================================ `; diff --git a/tests/format/flow/type-declarations/opaque.js b/tests/format/flow/type-declarations/opaque.js index 657d8fbef..77a1ac2e4 100644 --- a/tests/format/flow/type-declarations/opaque.js +++ b/tests/format/flow/type-declarations/opaque.js @@ -14,3 +14,14 @@ opaque type union = opaque type overloads = & ((x: string) => number) & ((x: number) => string); + +opaque type Counter super empty extends Box = Container; +opaque type Counter super Box = Container; + +opaque type Counter super Looooooooooooooooooog extends BoxLooooooooooooooooooog = Container; +opaque type Counter super BoxLooooooooooooooooooooooooooooooooog = Container; + +declare opaque type Counter super empty extends Box; +declare opaque type Counter super Box; +declare opaque type Counter super Looooooooooooooooooog extends BoxLooooooooooooooooooog; +declare opaque type Counter super BoxLooooooooooooooooooooooooooooooooooooooooooooooog; diff --git a/tests/unit/__snapshots__/visitor-keys.js.snap b/tests/unit/__snapshots__/visitor-keys.js.snap index a0f797dff..2ca397243 100644 --- a/tests/unit/__snapshots__/visitor-keys.js.snap +++ b/tests/unit/__snapshots__/visitor-keys.js.snap @@ -238,8 +238,10 @@ exports[`visitor keys estree 1`] = ` ], "DeclareOpaqueType": [ "id", + "lowerBound", "supertype", "typeParameters", + "upperBound", ], "DeclareTypeAlias": [ "id", @@ -702,8 +704,10 @@ exports[`visitor keys estree 1`] = ` "OpaqueType": [ "id", "impltype", + "lowerBound", "supertype", "typeParameters", + "upperBound", ], "OptionalCallExpression": [ "arguments",