diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md
index 4e84dc42..3e144431 100644
--- a/CHANGELOG.unreleased.md
+++ b/CHANGELOG.unreleased.md
@@ -87,15 +87,26 @@ Previous versions format text with whitespace after JSX incorrectly in mdx, this
123
```
-#### TypeScript/Flow: Union types inside of tuples ([#6381] by [@squidfunk])
+#### TypeScript/Flow: Union types inside tuples ([#6381] by [@squidfunk], [#6605] by [@thorn0])
-Previous versions would double-indent multi-line union types inside of
-tuples for TypeScipt and Flow and add a new line:
+Previous versions would double-indent multi-line union types inside
+tuples for TypeScript and Flow and add an empty line:
```ts
// Input
+type A = [
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD
+]
+
type B = [
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD,
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
@@ -108,8 +119,21 @@ type C = [
]
// Output (Prettier stable)
+type A = [
+
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD
+];
+
type B = [
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD,
+
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
@@ -124,24 +148,39 @@ type C = [
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
- ]
+ ]
| [
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
- ]
+ ]
];
// Output (Prettier master)
-type B = [
+type A = [
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
];
+type B = [
+ (
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD
+ ),
+ (
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD
+ )
+];
+
type C = [
| [
| AAAAAAAAAAAAAAAAAAAAAA
@@ -813,13 +852,13 @@ Previously, the flag was not applied on html attributes.
```
-#### TypeScript: Fix incorrectly removes double parentheses around types ([#6604] by [@sosukesuzuki])
+#### TypeScript: sometimes double parentheses around types were removed incorrectly ([#6604] by [@sosukesuzuki])
```ts
// Input
type A = 0 extends ((1 extends 2 ? 3 : 4)) ? 5 : 6;
-type B = ((0 extends 1 ? 2 : 3)) extends 4 ? 5 : 6:
+type B = ((0 extends 1 ? 2 : 3)) extends 4 ? 5 : 6;
type C = ((number | string))["toString"];
type D = ((keyof T1))["foo"];
@@ -887,6 +926,7 @@ function doSmth() {
[#6377]: https://github.com/prettier/prettier/pull/6377
[#6604]: https://github.com/prettier/prettier/pull/6604
[#6496]: https://github.com/prettier/prettier/pull/6496
+[#6605]: https://github.com/prettier/prettier/pull/6605
[@brainkim]: https://github.com/brainkim
[@duailibe]: https://github.com/duailibe
[@gavinjoyce]: https://github.com/gavinjoyce
diff --git a/src/language-js/clean.js b/src/language-js/clean.js
index b058c8cf..ee1209be 100644
--- a/src/language-js/clean.js
+++ b/src/language-js/clean.js
@@ -60,20 +60,6 @@ function clean(ast, newObj, parent) {
delete newObj.specifiers;
}
- // (TypeScript) bypass TSParenthesizedType
- if (ast.type === "TSParenthesizedType") {
- return newObj.typeAnnotation;
- }
-
- // (TypeScript) Bypass `& foo` and `| foo` into `foo`
- // https://github.com/microsoft/TypeScript/issues/30995
- if (
- (ast.type === "TSIntersectionType" || ast.type === "TSUnionType") &&
- ast.types.length === 1
- ) {
- return newObj.types[0];
- }
-
// We convert to
if (ast.type === "JSXOpeningElement") {
delete newObj.selfClosing;
diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js
index d0f4b79e..0c0ec43e 100644
--- a/src/language-js/needs-parens.js
+++ b/src/language-js/needs-parens.js
@@ -380,48 +380,6 @@ function needsParens(path, options) {
return false;
}
- case "TSParenthesizedType": {
- const grandParent = path.getParentNode(1);
-
- /**
- * const foo = (): (() => void) => (): void => null;
- * ^ ^
- */
- if (
- getUnparenthesizedNode(node).type === "TSFunctionType" &&
- parent.type === "TSTypeAnnotation" &&
- grandParent.type === "ArrowFunctionExpression" &&
- grandParent.returnType === parent
- ) {
- return true;
- }
-
- if (
- (parent.type === "TSTypeParameter" ||
- parent.type === "TypeParameter" ||
- parent.type === "TSTypeAliasDeclaration" ||
- parent.type === "TSTypeAnnotation" ||
- parent.type === "TSParenthesizedType" ||
- parent.type === "TSTypeParameterInstantiation") &&
- (grandParent.type !== "TSTypeOperator" &&
- grandParent.type !== "TSOptionalType")
- ) {
- return false;
- }
- // Delegate to inner TSParenthesizedType
- if (
- node.typeAnnotation.type === "TSParenthesizedType" &&
- parent.type !== "TSArrayType" &&
- parent.type !== "TSIndexedAccessType" &&
- parent.type !== "TSConditionalType" &&
- parent.type !== "TSIntersectionType" &&
- parent.type !== "TSUnionType"
- ) {
- return false;
- }
- return true;
- }
-
case "SequenceExpression":
switch (parent.type) {
case "ReturnStatement":
@@ -486,6 +444,36 @@ function needsParens(path, options) {
return false;
}
+ case "TSConditionalType":
+ if (parent.type === "TSConditionalType" && node === parent.extendsType) {
+ return true;
+ }
+ // fallthrough
+ case "TSFunctionType":
+ case "TSConstructorType":
+ if (parent.type === "TSConditionalType" && node === parent.checkType) {
+ return true;
+ }
+ // fallthrough
+ case "TSUnionType":
+ case "TSIntersectionType":
+ if (
+ parent.type === "TSUnionType" ||
+ parent.type === "TSIntersectionType"
+ ) {
+ return true;
+ }
+ // fallthrough
+ case "TSTypeOperator":
+ case "TSInferType":
+ return (
+ parent.type === "TSArrayType" ||
+ parent.type === "TSOptionalType" ||
+ parent.type === "TSRestType" ||
+ (parent.type === "TSIndexedAccessType" && node === parent.objectType) ||
+ parent.type === "TSTypeOperator"
+ );
+
case "ArrayTypeAnnotation":
return parent.type === "NullableTypeAnnotation";
@@ -790,12 +778,6 @@ function isStatement(node) {
);
}
-function getUnparenthesizedNode(node) {
- return node.type === "TSParenthesizedType"
- ? getUnparenthesizedNode(node.typeAnnotation)
- : node;
-}
-
function endsWithRightBracket(node) {
switch (node.type) {
case "ObjectExpression":
diff --git a/src/language-js/postprocess.js b/src/language-js/postprocess.js
index cdd12d36..b7fcc9ed 100644
--- a/src/language-js/postprocess.js
+++ b/src/language-js/postprocess.js
@@ -2,10 +2,10 @@
const { getLast } = require("../common/util");
-// fix unexpected locEnd caused by --no-semi style
function postprocess(ast, options) {
visitNode(ast, node => {
switch (node.type) {
+ // fix unexpected locEnd caused by --no-semi style
case "VariableDeclaration": {
const lastDeclaration = getLast(node.declarations);
if (lastDeclaration && lastDeclaration.init) {
@@ -13,6 +13,20 @@ function postprocess(ast, options) {
}
break;
}
+ // remove redundant TypeScript nodes
+ case "TSParenthesizedType": {
+ return node.typeAnnotation;
+ }
+ case "TSUnionType":
+ case "TSIntersectionType":
+ if (node.types.length === 1) {
+ // override loc, so that comments are attached properly
+ return Object.assign({}, node.types[0], {
+ loc: node.loc,
+ range: node.range
+ });
+ }
+ break;
}
});
@@ -44,14 +58,14 @@ function postprocess(ast, options) {
}
}
-function visitNode(node, fn) {
+function visitNode(node, fn, parent, property) {
if (!node || typeof node !== "object") {
return;
}
if (Array.isArray(node)) {
- for (const subNode of node) {
- visitNode(subNode, fn);
+ for (let i = 0; i < node.length; i++) {
+ visitNode(node[i], fn, node, i);
}
return;
}
@@ -61,10 +75,14 @@ function visitNode(node, fn) {
}
for (const key of Object.keys(node)) {
- visitNode(node[key], fn);
+ visitNode(node[key], fn, node, key);
}
- fn(node);
+ const replacement = fn(node);
+
+ if (replacement) {
+ parent[property] = replacement;
+ }
}
module.exports = postprocess;
diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js
index 8f78497b..23726fca 100644
--- a/src/language-js/printer-estree.js
+++ b/src/language-js/printer-estree.js
@@ -2820,32 +2820,21 @@ function printPathNoParens(path, options, print, args) {
join(concat([line, "| "]), printed)
]);
- let hasParens;
-
- if (n.type === "TSUnionType") {
- const grandParent = path.getNode(2);
- const greatGrandParent = path.getParentNode(2);
- const greatGreatGrandParent = path.getParentNode(3);
-
- hasParens =
- (parent.type === "TSParenthesizedType" &&
- (grandParent.type === "TSAsExpression" ||
- grandParent.type === "TSUnionType" ||
- grandParent.type === "TSIntersectionType" ||
- grandParent.type === "TSTypeOperator" ||
- grandParent.type === "TSArrayType" ||
- grandParent.type === "TSTupleType")) ||
- (greatGrandParent &&
- greatGrandParent.type === "TSParenthesizedType" &&
- greatGreatGrandParent &&
- (greatGreatGrandParent.type === "TSUnionType" ||
- greatGreatGrandParent.type === "TSIntersectionType"));
- } else {
- hasParens = pathNeedsParens(path, options);
+ if (pathNeedsParens(path, options)) {
+ return group(concat([indent(code), softline]));
}
- if (hasParens) {
- return group(concat([indent(code), softline]));
+ if (
+ (parent.type === "TupleTypeAnnotation" && parent.types.length > 1) ||
+ (parent.type === "TSTupleType" && parent.elementTypes.length > 1)
+ ) {
+ return group(
+ concat([
+ indent(concat([ifBreak(concat(["(", softline])), code])),
+ softline,
+ ifBreak(")")
+ ])
+ );
}
return group(shouldIndent ? indent(code) : code);
@@ -3173,9 +3162,6 @@ function printPathNoParens(path, options, print, args) {
]);
case "TSTypeQuery":
return concat(["typeof ", path.call(print, "exprName")]);
- case "TSParenthesizedType": {
- return path.call(print, "typeAnnotation");
- }
case "TSIndexSignature": {
const parent = path.getParentNode();
diff --git a/src/main/comments.js b/src/main/comments.js
index 3f5d776d..895dce48 100644
--- a/src/main/comments.js
+++ b/src/main/comments.js
@@ -320,8 +320,8 @@ function breakTies(tiesToBreak, text, options) {
assert.strictEqual(comment.precedingNode, precedingNode);
assert.strictEqual(comment.followingNode, followingNode);
- const gap = text.slice(options.locEnd(comment), gapEndPos).trim();
- if (gap === "" || /^\(+$/.test(gap)) {
+ const gap = text.slice(options.locEnd(comment), gapEndPos);
+ if (/^[\s(]*$/.test(gap)) {
gapEndPos = options.locStart(comment);
} else {
// The gap string contained something other than whitespace or open
diff --git a/tests/typescript/conformance/types/union/__snapshots__/jsfmt.spec.js.snap b/tests/typescript/conformance/types/union/__snapshots__/jsfmt.spec.js.snap
index 1271da85..e9e5c74a 100644
--- a/tests/typescript/conformance/types/union/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/typescript/conformance/types/union/__snapshots__/jsfmt.spec.js.snap
@@ -469,7 +469,6 @@ printWidth: 80
class C { }
class D extends C { foo() { } }
var x: C;
-var x: | C;
var x : C | D;
// A | B is equivalent to B | A.
@@ -492,7 +491,6 @@ class D extends C {
foo() {}
}
var x: C;
-var x: C;
var x: C | D;
// A | B is equivalent to B | A.
diff --git a/tests/typescript/conformance/types/union/unionTypeEquivalence.ts b/tests/typescript/conformance/types/union/unionTypeEquivalence.ts
index b9c78c75..821eb35d 100644
--- a/tests/typescript/conformance/types/union/unionTypeEquivalence.ts
+++ b/tests/typescript/conformance/types/union/unionTypeEquivalence.ts
@@ -2,7 +2,6 @@
class C { }
class D extends C { foo() { } }
var x: C;
-var x: | C;
var x : C | D;
// A | B is equivalent to B | A.
diff --git a/tests/typescript_conditional_types/__snapshots__/jsfmt.spec.js.snap b/tests/typescript_conditional_types/__snapshots__/jsfmt.spec.js.snap
index 34f70876..e06f96ae 100644
--- a/tests/typescript_conditional_types/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/typescript_conditional_types/__snapshots__/jsfmt.spec.js.snap
@@ -33,6 +33,16 @@ type Type06 = ((0 extends 1 ? 2 : 3)) extends 4 ? 5 : 6;
type Type07 = (((0 extends 1 ? 2 : 3))) extends 4 ? 5 : 6;
type Type08 = ((((0 extends 1 ? 2 : 3)))) extends 4 ? 5 : 6;
+type T1 = () => void extends T ? U : V;
+type T1a = () => (void extends T ? U : V);
+type T1b = () => (void) extends T ? U : V;
+type T2 = (() => void) extends T ? U : V;
+
+type U1 = new () => X extends T ? U : V;
+type U1a = new () => (X extends T ? U : V);
+type U1b = new () => (X) extends T ? U : V;
+type U2 = (new () => X) extends T ? U : V;
+
=====================================output=====================================
export type DeepReadonly = T extends any[]
? DeepReadonlyArray
@@ -71,6 +81,16 @@ type Type06 = (0 extends 1 ? 2 : 3) extends 4 ? 5 : 6;
type Type07 = (0 extends 1 ? 2 : 3) extends 4 ? 5 : 6;
type Type08 = (0 extends 1 ? 2 : 3) extends 4 ? 5 : 6;
+type T1 = () => void extends T ? U : V;
+type T1a = () => void extends T ? U : V;
+type T1b = () => void extends T ? U : V;
+type T2 = (() => void) extends T ? U : V;
+
+type U1 = new () => X extends T ? U : V;
+type U1a = new () => X extends T ? U : V;
+type U1b = new () => X extends T ? U : V;
+type U2 = (new () => X) extends T ? U : V;
+
================================================================================
`;
@@ -82,6 +102,12 @@ printWidth: 80
=====================================input======================================
type TestReturnType any> = T extends (...args: any[]) => infer R ? R : any;
+type Unpacked =
+ T extends (infer U)[] ? U :
+ T extends (...args: any[]) => infer U ? U :
+ T extends Promise ? U :
+ T;
+
=====================================output=====================================
type TestReturnType any> = T extends (
...args: any[]
@@ -89,5 +115,13 @@ type TestReturnType any> = T extends (
? R
: any;
+type Unpacked = T extends (infer U)[]
+ ? U
+ : T extends (...args: any[]) => infer U
+ ? U
+ : T extends Promise
+ ? U
+ : T;
+
================================================================================
`;
diff --git a/tests/typescript_conditional_types/conditonal-types.ts b/tests/typescript_conditional_types/conditonal-types.ts
index e5147c52..b2ce6ad0 100644
--- a/tests/typescript_conditional_types/conditonal-types.ts
+++ b/tests/typescript_conditional_types/conditonal-types.ts
@@ -24,3 +24,13 @@ type Type05 = (0 extends 1 ? 2 : 3) extends 4 ? 5 : 6;
type Type06 = ((0 extends 1 ? 2 : 3)) extends 4 ? 5 : 6;
type Type07 = (((0 extends 1 ? 2 : 3))) extends 4 ? 5 : 6;
type Type08 = ((((0 extends 1 ? 2 : 3)))) extends 4 ? 5 : 6;
+
+type T1 = () => void extends T ? U : V;
+type T1a = () => (void extends T ? U : V);
+type T1b = () => (void) extends T ? U : V;
+type T2 = (() => void) extends T ? U : V;
+
+type U1 = new () => X extends T ? U : V;
+type U1a = new () => (X extends T ? U : V);
+type U1b = new () => (X) extends T ? U : V;
+type U2 = (new () => X) extends T ? U : V;
diff --git a/tests/typescript_conditional_types/infer-type.ts b/tests/typescript_conditional_types/infer-type.ts
index ed8e81c8..eb20f81c 100644
--- a/tests/typescript_conditional_types/infer-type.ts
+++ b/tests/typescript_conditional_types/infer-type.ts
@@ -1 +1,7 @@
type TestReturnType any> = T extends (...args: any[]) => infer R ? R : any;
+
+type Unpacked =
+ T extends (infer U)[] ? U :
+ T extends (...args: any[]) => infer U ? U :
+ T extends Promise ? U :
+ T;
diff --git a/tests/typescript_intersection/__snapshots__/jsfmt.spec.js.snap b/tests/typescript_intersection/__snapshots__/jsfmt.spec.js.snap
index 4a1fd0b2..8c7b31db 100644
--- a/tests/typescript_intersection/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/typescript_intersection/__snapshots__/jsfmt.spec.js.snap
@@ -11,12 +11,90 @@ type B = ((number | string)) & boolean;
type C = (((number | string))) & boolean;
type D = ((((number | string)))) & boolean;
+let b1 : C;
+let b2 : & C;
+let b3 : (& C);
+let b4 : & (C);
+let b5 : (& (C));
+let b6 : /*1*/ & C;
+let b7 : /*1*/ & (C);
+let b8 : /*1*/ (& C);
+let b9 : (/*1*/ & C);
+let b10: /*1*/ & /*2*/ C;
+let b11: /*1*/ (& /*2*/ C);
+
+let bb1: /*1*/ & /*2*/ C & D;
+let bb2: /*1*/ & /*2*/ C & /*3*/ D;
+let bb3: /*1*/ & /*2*/ C & /*3*/ D /*5*/;
+
+type B2 = & C;
+type B3 = (& C);
+type B4 = & (C);
+type B5 = (& (C));
+type B6 = /*1*/ & C;
+type B7 = /*1*/ & (C);
+type B8 = /*1*/ (& C);
+type B9 = (/*1*/ & C);
+type B10 = /*1*/ & /*2*/ C;
+type B11 = /*1*/ (& /*2*/ C);
+type B12 = /*1*/ & ( (C));
+
+type Bb1 = /*1*/ & /*2*/ C & D;
+type Bb2 = /*1*/ & /*2*/ C & /*3*/ D;
+type Bb3 = /*1*/ & /*2*/ C & /*3*/ D /*4*/;
+
+type D1 = /*1*/ | a & b;
+type D2 = /*1*/ | a & (b);
+type D3 = /*1*/ | a & (| b);
+type D4 = /*1*/ | (a & b);
+type D5 = /*1*/ (| a & b);
+type D6 /*0*/ = /*1*/ (| a & b);
+
=====================================output=====================================
type A = (number | string) & boolean;
type B = (number | string) & boolean;
type C = (number | string) & boolean;
type D = (number | string) & boolean;
+let b1: C;
+let b2: C;
+let b3: C;
+let b4: C;
+let b5: C;
+let b6: /*1*/ C;
+let b7: /*1*/ C;
+let b8: /*1*/ C;
+let b9: /*1*/ C;
+let b10: /*1*/ /*2*/ C;
+let b11: /*1*/ /*2*/ C;
+
+let bb1: /*1*/ /*2*/ C & D;
+let bb2: /*1*/ /*2*/ C & /*3*/ D;
+let bb3: /*1*/ /*2*/ C & /*3*/ D /*5*/;
+
+type B2 = C;
+type B3 = C;
+type B4 = C;
+type B5 = C;
+type B6 = /*1*/ C;
+type B7 = /*1*/ C;
+type B8 = /*1*/ C;
+type B9 = /*1*/ C;
+type B10 = /*1*/ /*2*/ C;
+type B11 = /*1*/ /*2*/ C;
+type B12 = /*1*/ C;
+
+type Bb1 = /*1*/ /*2*/ C & D;
+type Bb2 = /*1*/ /*2*/ C & /*3*/ D;
+type Bb3 = /*1*/ /*2*/ C & /*3*/ D /*4*/;
+
+type D1 = /*1*/ a & b;
+type D2 = /*1*/ a & b;
+type D3 = /*1*/ a & b;
+type D4 = /*1*/ a & b;
+type D5 = /*1*/ a & b;
+type D6 /*0*/ = /*1*/ a & b;
+
================================================================================
`;
@@ -32,11 +110,89 @@ type B = ((number | string)) & boolean;
type C = (((number | string))) & boolean;
type D = ((((number | string)))) & boolean;
+let b1 : C;
+let b2 : & C;
+let b3 : (& C);
+let b4 : & (C);
+let b5 : (& (C));
+let b6 : /*1*/ & C;
+let b7 : /*1*/ & (C);
+let b8 : /*1*/ (& C);
+let b9 : (/*1*/ & C);
+let b10: /*1*/ & /*2*/ C;
+let b11: /*1*/ (& /*2*/ C);
+
+let bb1: /*1*/ & /*2*/ C & D;
+let bb2: /*1*/ & /*2*/ C & /*3*/ D;
+let bb3: /*1*/ & /*2*/ C & /*3*/ D /*5*/;
+
+type B2 = & C;
+type B3 = (& C);
+type B4 = & (C);
+type B5 = (& (C));
+type B6 = /*1*/ & C;
+type B7 = /*1*/ & (C);
+type B8 = /*1*/ (& C);
+type B9 = (/*1*/ & C);
+type B10 = /*1*/ & /*2*/ C;
+type B11 = /*1*/ (& /*2*/ C);
+type B12 = /*1*/ & ( (C));
+
+type Bb1 = /*1*/ & /*2*/ C & D;
+type Bb2 = /*1*/ & /*2*/ C & /*3*/ D;
+type Bb3 = /*1*/ & /*2*/ C & /*3*/ D /*4*/;
+
+type D1 = /*1*/ | a & b;
+type D2 = /*1*/ | a & (b);
+type D3 = /*1*/ | a & (| b);
+type D4 = /*1*/ | (a & b);
+type D5 = /*1*/ (| a & b);
+type D6 /*0*/ = /*1*/ (| a & b);
+
=====================================output=====================================
type A = (number | string) & boolean
type B = (number | string) & boolean
type C = (number | string) & boolean
type D = (number | string) & boolean
+let b1: C
+let b2: C
+let b3: C
+let b4: C
+let b5: C
+let b6: /*1*/ C
+let b7: /*1*/ C
+let b8: /*1*/ C
+let b9: /*1*/ C
+let b10: /*1*/ /*2*/ C
+let b11: /*1*/ /*2*/ C
+
+let bb1: /*1*/ /*2*/ C & D
+let bb2: /*1*/ /*2*/ C & /*3*/ D
+let bb3: /*1*/ /*2*/ C & /*3*/ D /*5*/
+
+type B2 = C
+type B3 = C
+type B4 = C
+type B5 = C
+type B6 = /*1*/ C
+type B7 = /*1*/ C
+type B8 = /*1*/ C
+type B9 = /*1*/ C
+type B10 = /*1*/ /*2*/ C
+type B11 = /*1*/ /*2*/ C
+type B12 = /*1*/ C
+
+type Bb1 = /*1*/ /*2*/ C & D
+type Bb2 = /*1*/ /*2*/ C & /*3*/ D
+type Bb3 = /*1*/ /*2*/ C & /*3*/ D /*4*/
+
+type D1 = /*1*/ a & b
+type D2 = /*1*/ a & b
+type D3 = /*1*/ a & b
+type D4 = /*1*/ a & b
+type D5 = /*1*/ a & b
+type D6 /*0*/ = /*1*/ a & b
+
================================================================================
`;
diff --git a/tests/typescript_intersection/intersection-parens.ts b/tests/typescript_intersection/intersection-parens.ts
index a6077856..b19671ac 100644
--- a/tests/typescript_intersection/intersection-parens.ts
+++ b/tests/typescript_intersection/intersection-parens.ts
@@ -2,3 +2,42 @@ type A = (number | string) & boolean;
type B = ((number | string)) & boolean;
type C = (((number | string))) & boolean;
type D = ((((number | string)))) & boolean;
+
+let b1 : C;
+let b2 : & C;
+let b3 : (& C);
+let b4 : & (C);
+let b5 : (& (C));
+let b6 : /*1*/ & C;
+let b7 : /*1*/ & (C);
+let b8 : /*1*/ (& C);
+let b9 : (/*1*/ & C);
+let b10: /*1*/ & /*2*/ C;
+let b11: /*1*/ (& /*2*/ C);
+
+let bb1: /*1*/ & /*2*/ C & D;
+let bb2: /*1*/ & /*2*/ C & /*3*/ D;
+let bb3: /*1*/ & /*2*/ C & /*3*/ D /*5*/;
+
+type B2 = & C;
+type B3 = (& C);
+type B4 = & (C);
+type B5 = (& (C));
+type B6 = /*1*/ & C;
+type B7 = /*1*/ & (C);
+type B8 = /*1*/ (& C);
+type B9 = (/*1*/ & C);
+type B10 = /*1*/ & /*2*/ C;
+type B11 = /*1*/ (& /*2*/ C);
+type B12 = /*1*/ & ( (C));
+
+type Bb1 = /*1*/ & /*2*/ C & D;
+type Bb2 = /*1*/ & /*2*/ C & /*3*/ D;
+type Bb3 = /*1*/ & /*2*/ C & /*3*/ D /*4*/;
+
+type D1 = /*1*/ | a & b;
+type D2 = /*1*/ | a & (b);
+type D3 = /*1*/ | a & (| b);
+type D4 = /*1*/ | (a & b);
+type D5 = /*1*/ (| a & b);
+type D6 /*0*/ = /*1*/ (| a & b);
diff --git a/tests/typescript_optional_type/__snapshots__/jsfmt.spec.js.snap b/tests/typescript_optional_type/__snapshots__/jsfmt.spec.js.snap
index 01af5d6b..fcf68d50 100644
--- a/tests/typescript_optional_type/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/typescript_optional_type/__snapshots__/jsfmt.spec.js.snap
@@ -7,9 +7,11 @@ printWidth: 80
| printWidth
=====================================input======================================
type T = [("a" | "b")?];
+type TupleWithOptional = [number, (1 extends 2 ? string[] : number[])?];
=====================================output=====================================
type T = [("a" | "b")?];
+type TupleWithOptional = [number, (1 extends 2 ? string[] : number[])?];
================================================================================
`;
diff --git a/tests/typescript_optional_type/complex.ts b/tests/typescript_optional_type/complex.ts
index f5c170a3..b6cda8b4 100644
--- a/tests/typescript_optional_type/complex.ts
+++ b/tests/typescript_optional_type/complex.ts
@@ -1 +1,2 @@
type T = [("a" | "b")?];
+type TupleWithOptional = [number, (1 extends 2 ? string[] : number[])?];
diff --git a/tests/typescript_rest_type/__snapshots__/jsfmt.spec.js.snap b/tests/typescript_rest_type/__snapshots__/jsfmt.spec.js.snap
index fef6f895..1334dc24 100644
--- a/tests/typescript_rest_type/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/typescript_rest_type/__snapshots__/jsfmt.spec.js.snap
@@ -1,5 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`complex.ts 1`] = `
+====================================options=====================================
+parsers: ["typescript"]
+printWidth: 80
+ | printWidth
+=====================================input======================================
+type TupleWithRest = [number, ...(1 extends 2 ? string[] : number[])];
+
+=====================================output=====================================
+type TupleWithRest = [number, ...(1 extends 2 ? string[] : number[])];
+
+================================================================================
+`;
+
exports[`simple.ts 1`] = `
====================================options=====================================
parsers: ["typescript"]
diff --git a/tests/typescript_rest_type/complex.ts b/tests/typescript_rest_type/complex.ts
new file mode 100644
index 00000000..db303842
--- /dev/null
+++ b/tests/typescript_rest_type/complex.ts
@@ -0,0 +1 @@
+type TupleWithRest = [number, ...(1 extends 2 ? string[] : number[])];
diff --git a/tests/typescript_union/__snapshots__/jsfmt.spec.js.snap b/tests/typescript_union/__snapshots__/jsfmt.spec.js.snap
index 2cf4944c..2bb487bd 100644
--- a/tests/typescript_union/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/typescript_union/__snapshots__/jsfmt.spec.js.snap
@@ -138,7 +138,7 @@ type State = {
} & (
| { discriminant: "FOO"; foo: any }
| { discriminant: "BAR"; bar: any }
- | { discriminant: "BAZ"; baz: any }
+ | { discriminant: "BAZ"; baz: any }
);
const foo = [abc, def, ghi, jkl, mno, pqr, stu, vwx, yz] as (
@@ -169,6 +169,49 @@ const foo:
| DDDDDDDDDDDDDDDDDDDDDD
) = bar;
+let a1 : C;
+let a2 : | C;
+let a3 : (| C);
+let a4 : | (C);
+let a5 : (| (C));
+let a6 : /*1*/ | C;
+let a7 : /*1*/ | (C);
+let a8 : /*1*/ (| C);
+let a9 : (/*1*/ | C);
+let a10: /*1*/ | /*2*/ C;
+let a11: /*1*/ (| /*2*/ C);
+
+let aa1: /*1*/ | /*2*/ C | D;
+let aa2: /*1*/ | /*2*/ C | /*3*/ D;
+let aa3: /*1*/ | /*2*/ C | /*3*/ D /*4*/;
+
+type A1 = C;
+type A2 = | C;
+type A3 = (| C);
+type A4 = | (C);
+type A5 = (| (C));
+type A6 = /*1*/ | C;
+type A7 = /*1*/ | (C);
+type A8 = /*1*/ (| C);
+type A9 = (/*1*/ | C);
+type A10 = /*1*/ | /*2*/ C;
+type A11 = /*1*/ (| /*2*/ C);
+type A12 = /*1*/ | ( (C));
+type A13 = /*1*/ ( (C));
+
+type Aa1 = /*1*/ | /*2*/ C | D;
+type Aa2 = /*1*/ | /*2*/ C | /*3*/ D;
+type Aa3 = /*1*/ | /*2*/ C | /*3*/ D /*4*/;
+
+type C1 = /*1*/ & a | b;
+type C2 = /*1*/ & a | (b);
+type C3 = /*1*/ & a | (& b);
+type C4 = /*1*/ & (a | b);
+type C5 = /*1*/ (& a | b);
+type C6 /*0*/ = /*1*/ (& a | b);
+
+type Ctor = (new () => X) | Y;
+
=====================================output=====================================
export type A =
| aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -236,6 +279,49 @@ const foo:
| DDDDDDDDDDDDDDDDDDDDDD
) = bar;
+let a1: C;
+let a2: C;
+let a3: C;
+let a4: C;
+let a5: C;
+let a6: /*1*/ C;
+let a7: /*1*/ C;
+let a8: /*1*/ C;
+let a9: /*1*/ C;
+let a10: /*1*/ /*2*/ C;
+let a11: /*1*/ /*2*/ C;
+
+let aa1: /*1*/ /*2*/ C | D;
+let aa2: /*1*/ /*2*/ C | /*3*/ D;
+let aa3: /*1*/ /*2*/ C | /*3*/ D /*4*/;
+
+type A1 = C;
+type A2 = C;
+type A3 = C;
+type A4 = C;
+type A5 = C;
+type A6 = /*1*/ C;
+type A7 = /*1*/ C;
+type A8 = /*1*/ C;
+type A9 = /*1*/ C;
+type A10 = /*1*/ /*2*/ C;
+type A11 = /*1*/ /*2*/ C;
+type A12 = /*1*/ C;
+type A13 = /*1*/ C;
+
+type Aa1 = /*1*/ /*2*/ C | D;
+type Aa2 = /*1*/ /*2*/ C | /*3*/ D;
+type Aa3 = /*1*/ /*2*/ C | /*3*/ D /*4*/;
+
+type C1 = /*1*/ a | b;
+type C2 = /*1*/ a | b;
+type C3 = /*1*/ a | b;
+type C4 = /*1*/ a | b;
+type C5 = /*1*/ a | b;
+type C6 /*0*/ = /*1*/ a | b;
+
+type Ctor = (new () => X) | Y;
+
================================================================================
`;
@@ -284,6 +370,15 @@ type B = [
| DDDDDDDDDDDDDDDDDDDDDD
]
+type B1 = [
+ (
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD
+ )
+]
+
type C = [
| [AAAAAAAAAAAAAAAAAAAAAA | BBBBBBBBBBBBBBBBBBBBBB | CCCCCCCCCCCCCCCCCCCCCC | DDDDDDDDDDDDDDDDDDDDDD]
| [AAAAAAAAAAAAAAAAAAAAAA | BBBBBBBBBBBBBBBBBBBBBB | CCCCCCCCCCCCCCCCCCCCCC | DDDDDDDDDDDDDDDDDDDDDD]
@@ -294,7 +389,7 @@ type D = [
(AAAAAAAAAAAAAAAAAAAAAA | BBBBBBBBBBBBBBBBBBBBBB | CCCCCCCCCCCCCCCCCCCCCC | DDDDDDDDDDDDDDDDDDDDDD)
]
-type E = [
+type D1 = [
(
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
@@ -308,6 +403,29 @@ type E = [
| DDDDDDDDDDDDDDDDDDDDDD
)
]
+
+type D2 = [
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD,
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD
+]
+
+type E = [ AA | BB, AA | BB ]
+
+type F = [
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD,
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+]
+
=====================================output=====================================
type A = [
| AAAAAAAAAAAAAAAAAAAAAA
@@ -323,6 +441,13 @@ type B = [
| DDDDDDDDDDDDDDDDDDDDDD
];
+type B1 = [
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD
+];
+
type C = [
| [
| AAAAAAAAAAAAAAAAAAAAAA
@@ -353,7 +478,7 @@ type D = [
)
];
-type E = [
+type D1 = [
(
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
@@ -368,5 +493,32 @@ type E = [
)
];
+type D2 = [
+ (
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD
+ ),
+ (
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD
+ )
+];
+
+type E = [AA | BB, AA | BB];
+
+type F = [
+ (
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD
+ ),
+ AAAAAAAAAAAAAAAAAAAAAA | BBBBBBBBBBBBBBBBBBBBBB
+];
+
================================================================================
`;
diff --git a/tests/typescript_union/union-parens.ts b/tests/typescript_union/union-parens.ts
index ddc8e10b..6b9c086f 100644
--- a/tests/typescript_union/union-parens.ts
+++ b/tests/typescript_union/union-parens.ts
@@ -36,7 +36,7 @@ type State = {
} & (
| { discriminant: "FOO"; foo: any }
| { discriminant: "BAR"; bar: any }
- | { discriminant: "BAZ"; baz: any }
+ | { discriminant: "BAZ"; baz: any }
);
const foo = [abc, def, ghi, jkl, mno, pqr, stu, vwx, yz] as (
@@ -66,3 +66,46 @@ const foo:
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
) = bar;
+
+let a1 : C;
+let a2 : | C;
+let a3 : (| C);
+let a4 : | (C);
+let a5 : (| (C));
+let a6 : /*1*/ | C;
+let a7 : /*1*/ | (C);
+let a8 : /*1*/ (| C);
+let a9 : (/*1*/ | C);
+let a10: /*1*/ | /*2*/ C;
+let a11: /*1*/ (| /*2*/ C);
+
+let aa1: /*1*/ | /*2*/ C | D;
+let aa2: /*1*/ | /*2*/ C | /*3*/ D;
+let aa3: /*1*/ | /*2*/ C | /*3*/ D /*4*/;
+
+type A1 = C;
+type A2 = | C;
+type A3 = (| C);
+type A4 = | (C);
+type A5 = (| (C));
+type A6 = /*1*/ | C;
+type A7 = /*1*/ | (C);
+type A8 = /*1*/ (| C);
+type A9 = (/*1*/ | C);
+type A10 = /*1*/ | /*2*/ C;
+type A11 = /*1*/ (| /*2*/ C);
+type A12 = /*1*/ | ( (C));
+type A13 = /*1*/ ( (C));
+
+type Aa1 = /*1*/ | /*2*/ C | D;
+type Aa2 = /*1*/ | /*2*/ C | /*3*/ D;
+type Aa3 = /*1*/ | /*2*/ C | /*3*/ D /*4*/;
+
+type C1 = /*1*/ & a | b;
+type C2 = /*1*/ & a | (b);
+type C3 = /*1*/ & a | (& b);
+type C4 = /*1*/ & (a | b);
+type C5 = /*1*/ (& a | b);
+type C6 /*0*/ = /*1*/ (& a | b);
+
+type Ctor = (new () => X) | Y;
diff --git a/tests/typescript_union/within-tuple.ts b/tests/typescript_union/within-tuple.ts
index 12f40cb3..7539bc9d 100644
--- a/tests/typescript_union/within-tuple.ts
+++ b/tests/typescript_union/within-tuple.ts
@@ -7,6 +7,15 @@ type B = [
| DDDDDDDDDDDDDDDDDDDDDD
]
+type B1 = [
+ (
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD
+ )
+]
+
type C = [
| [AAAAAAAAAAAAAAAAAAAAAA | BBBBBBBBBBBBBBBBBBBBBB | CCCCCCCCCCCCCCCCCCCCCC | DDDDDDDDDDDDDDDDDDDDDD]
| [AAAAAAAAAAAAAAAAAAAAAA | BBBBBBBBBBBBBBBBBBBBBB | CCCCCCCCCCCCCCCCCCCCCC | DDDDDDDDDDDDDDDDDDDDDD]
@@ -17,7 +26,7 @@ type D = [
(AAAAAAAAAAAAAAAAAAAAAA | BBBBBBBBBBBBBBBBBBBBBB | CCCCCCCCCCCCCCCCCCCCCC | DDDDDDDDDDDDDDDDDDDDDD)
]
-type E = [
+type D1 = [
(
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
@@ -30,4 +39,26 @@ type E = [
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
)
-]
\ No newline at end of file
+]
+
+type D2 = [
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD,
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD
+]
+
+type E = [ AA | BB, AA | BB ]
+
+type F = [
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+ | CCCCCCCCCCCCCCCCCCCCCC
+ | DDDDDDDDDDDDDDDDDDDDDD,
+ | AAAAAAAAAAAAAAAAAAAAAA
+ | BBBBBBBBBBBBBBBBBBBBBB
+]