diff --git a/common/changes/@typespec/compiler/fix-formatter-keep-parens-valueof_2023-11-21-18-00.json b/common/changes/@typespec/compiler/fix-formatter-keep-parens-valueof_2023-11-21-18-00.json new file mode 100644 index 0000000000..04a64da9b6 --- /dev/null +++ b/common/changes/@typespec/compiler/fix-formatter-keep-parens-valueof_2023-11-21-18-00.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@typespec/compiler", + "comment": "Formatter: Fix: `valueof` expression with parentheses around will preserve them when they are meaningful(For example inside a union or array expression)", + "type": "none" + } + ], + "packageName": "@typespec/compiler" +} diff --git a/packages/compiler/src/formatter/print/needs-parens.ts b/packages/compiler/src/formatter/print/needs-parens.ts index 45333859d6..a9a4e58497 100644 --- a/packages/compiler/src/formatter/print/needs-parens.ts +++ b/packages/compiler/src/formatter/print/needs-parens.ts @@ -16,6 +16,12 @@ export function needsParens(path: AstPath, options: TypeSpecPrettierOption // eslint-disable-next-line deprecation/deprecation const node = path.getValue(); switch (node.kind) { + case SyntaxKind.ValueOfExpression: + return ( + parent.kind === SyntaxKind.UnionExpression || + parent.kind === SyntaxKind.ArrayExpression || + parent.kind === SyntaxKind.IntersectionExpression + ); case SyntaxKind.IntersectionExpression: return ( parent.kind === SyntaxKind.UnionExpression || parent.kind === SyntaxKind.ArrayExpression diff --git a/packages/compiler/test/formatter/formatter.test.ts b/packages/compiler/test/formatter/formatter.test.ts index 5c7f9faf0b..4c33378cbb 100644 --- a/packages/compiler/test/formatter/formatter.test.ts +++ b/packages/compiler/test/formatter/formatter.test.ts @@ -2429,6 +2429,41 @@ model Foo { }); }); + describe("valueof", () => { + it("format simple valueof", async () => { + await assertFormat({ + code: ` +alias A = valueof string; +`, + expected: ` +alias A = valueof string; +`, + }); + }); + + it("keeps parentheses around valueof inside a union", async () => { + await assertFormat({ + code: ` +alias A = (valueof string) | Model; +`, + expected: ` +alias A = (valueof string) | Model; +`, + }); + }); + + it("keeps parentheses around valueof inside a array expression", async () => { + await assertFormat({ + code: ` +alias A = (valueof string)[]; +`, + expected: ` +alias A = (valueof string)[]; +`, + }); + }); + }); + describe("projections", () => { it("format projections", async () => { await assertFormat({