Get rid of TSParenthesizedType nodes before proceeding with formatting (#6605)

* get rid of TSParenthesizedType nodes before proceeding with formatting

* fix parens for TSIndexedAccessType, TSFunctionType, TSConditionalType

fixes #6603

* workaround edge cases with one-item unions and intersections

* fix parens for TSInferType

* fix parens for rest elements in tuple types

* refactoring

* fix function types in conditional types

* move tests for rest and optional tuple elements

* fix comment issues

* tests for unions and intersections

* add parens around multiline unions in tuple

* move the parens check for TS nodes closer to the one for Flow nodes

* update CHANGELOG.unreleased.md

* remove dead code

* fix parens for TSConstructorType

* better wording in CHANGELOG.unreleased.md
master
Georgii Dolzhykov 2019-10-14 15:00:21 +03:00 committed by Evilebot Tnawi
parent f8a4a61a62
commit 977b828666
20 changed files with 612 additions and 114 deletions

View File

@ -87,15 +87,26 @@ Previous versions format text with whitespace after JSX incorrectly in mdx, this
</Hello> 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:
<!-- prettier-ignore -->
```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.
<div class='a-class-name'></div>
```
#### TypeScript: Fix incorrectly removes double parentheses around types ([#6604] by [@sosukesuzuki])
#### TypeScript: sometimes double parentheses around types were removed incorrectly ([#6604] by [@sosukesuzuki])
<!-- prettier-ignore -->
```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

View File

@ -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 <div></div> to <div />
if (ast.type === "JSXOpeningElement") {
delete newObj.selfClosing;

View File

@ -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":

View File

@ -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;

View File

@ -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();

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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> = T extends any[]
? DeepReadonlyArray<T[number]>
@ -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<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : any;
type Unpacked<T> =
T extends (infer U)[] ? U :
T extends (...args: any[]) => infer U ? U :
T extends Promise<infer U> ? U :
T;
=====================================output=====================================
type TestReturnType<T extends (...args: any[]) => any> = T extends (
...args: any[]
@ -89,5 +115,13 @@ type TestReturnType<T extends (...args: any[]) => any> = T extends (
? R
: any;
type Unpacked<T> = T extends (infer U)[]
? U
: T extends (...args: any[]) => infer U
? U
: T extends Promise<infer U>
? U
: T;
================================================================================
`;

View File

@ -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;

View File

@ -1 +1,7 @@
type TestReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : any;
type Unpacked<T> =
T extends (infer U)[] ? U :
T extends (...args: any[]) => infer U ? U :
T extends Promise<infer U> ? U :
T;

View File

@ -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
================================================================================
`;

View File

@ -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);

View File

@ -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[])?];
================================================================================
`;

View File

@ -1 +1,2 @@
type T = [("a" | "b")?];
type TupleWithOptional = [number, (1 extends 2 ? string[] : number[])?];

View File

@ -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"]

View File

@ -0,0 +1 @@
type TupleWithRest = [number, ...(1 extends 2 ? string[] : number[])];

View File

@ -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
];
================================================================================
`;

View File

@ -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;

View File

@ -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
)
]
]
type D2 = [
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD,
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD
]
type E = [ AA | BB, AA | BB ]
type F = [
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
| CCCCCCCCCCCCCCCCCCCCCC
| DDDDDDDDDDDDDDDDDDDDDD,
| AAAAAAAAAAAAAAAAAAAAAA
| BBBBBBBBBBBBBBBBBBBBBB
]