diff --git a/src/clean-ast.js b/src/clean-ast.js index 976d4ea0..04ffbf8e 100644 --- a/src/clean-ast.js +++ b/src/clean-ast.js @@ -98,11 +98,10 @@ function massageAST(ast) { delete newObj.specifiers; } - // (TypeScript) allow parenthesization of TSFunctionType + // (TypeScript) bypass TSParenthesizedType if ( ast.type === "TSParenthesizedType" && - ast.typeAnnotation.type === "TypeAnnotation" && - ast.typeAnnotation.typeAnnotation.type === "TSFunctionType" + ast.typeAnnotation.type === "TypeAnnotation" ) { return newObj.typeAnnotation.typeAnnotation; } diff --git a/src/fast-path.js b/src/fast-path.js index 129c11df..5c52a69e 100644 --- a/src/fast-path.js +++ b/src/fast-path.js @@ -343,6 +343,23 @@ FastPath.prototype.needsParens = function() { return false; } + case "TSParenthesizedType": { + if ( + (parent.type === "VariableDeclarator" || + parent.type === "TypeAnnotation" || + parent.type === "GenericTypeAnnotation") && + (node.typeAnnotation.type === "TypeAnnotation" && + node.typeAnnotation.typeAnnotation.type !== "TSFunctionType") + ) { + return false; + } + // Delegate to inner TSParenthesizedType + if (node.typeAnnotation.type === "TSParenthesizedType") { + return false; + } + return true; + } + case "SequenceExpression": switch (parent.type) { case "ReturnStatement": diff --git a/src/printer.js b/src/printer.js index 9daca9b4..ba10b245 100644 --- a/src/printer.js +++ b/src/printer.js @@ -2353,8 +2353,9 @@ function genericPrintNoParens(path, options, print, args) { ]); case "TSTypeQuery": return concat(["typeof ", path.call(print, "exprName")]); - case "TSParenthesizedType": - return concat(["(", path.call(print, "typeAnnotation"), ")"]); + case "TSParenthesizedType": { + return path.call(print, "typeAnnotation"); + } case "TSIndexSignature": { const parent = path.getParentNode(); let printedParams = []; diff --git a/tests/typescript/custom/typeParameters/__snapshots__/jsfmt.spec.js.snap b/tests/typescript/custom/typeParameters/__snapshots__/jsfmt.spec.js.snap index 1801826e..7477dd8f 100644 --- a/tests/typescript/custom/typeParameters/__snapshots__/jsfmt.spec.js.snap +++ b/tests/typescript/custom/typeParameters/__snapshots__/jsfmt.spec.js.snap @@ -50,7 +50,7 @@ type AwkwardlyLongFunctionTypeDefinition = < arg1: GenericTypeNumberOne, arg2: GenericTypeNumberTwo, arg3: GenericTypeNumberThree -) => (GenericTypeNumberOne | GenericTypeNumberTwo | GenericTypeNumberThree); +) => GenericTypeNumberOne | GenericTypeNumberTwo | GenericTypeNumberThree; `; diff --git a/tests/typescript_union/__snapshots__/jsfmt.spec.js.snap b/tests/typescript_union/__snapshots__/jsfmt.spec.js.snap index 5e2fecdd..41dd1eca 100644 --- a/tests/typescript_union/__snapshots__/jsfmt.spec.js.snap +++ b/tests/typescript_union/__snapshots__/jsfmt.spec.js.snap @@ -68,3 +68,69 @@ type window = Window & { }; `; + +exports[`union-parens.ts 1`] = ` + +export type A = ( + | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +); + +export type B = ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +); + +export type C = + | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; + +export type D = + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; + +export type Multi = (string | number)[]; + +function f(): (string | number) {} + +var x: (string | number); +var y: ((string | number)); + +class Foo {} + +interface Interface { + i: (X | Y) & Z; + j: Partial<(X | Y)>; +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +export type A = + | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; + +export type B = + | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; + +export type C = + | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; + +export type D = + | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; + +export type Multi = (string | number)[]; + +function f(): string | number {} + +var x: string | number; +var y: string | number; + +class Foo {} + +interface Interface { + i: (X | Y) & Z; + j: Partial; +} + +`; diff --git a/tests/typescript_union/union-parens.ts b/tests/typescript_union/union-parens.ts new file mode 100644 index 00000000..2b1896fe --- /dev/null +++ b/tests/typescript_union/union-parens.ts @@ -0,0 +1,32 @@ + +export type A = ( + | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +); + +export type B = ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +); + +export type C = + | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; + +export type D = + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; + +export type Multi = (string | number)[]; + +function f(): (string | number) {} + +var x: (string | number); +var y: ((string | number)); + +class Foo {} + +interface Interface { + i: (X | Y) & Z; + j: Partial<(X | Y)>; +}