Somewhat improve conditional type alias (#15811)

Co-authored-by: fisker Cheung <lionkay@gmail.com>
This commit is contained in:
Seiyaandfisker Cheung authored and GitHub committed 2023-12-28 23:46:34 +09:00
1 parent b9d0c993b9
commit 82db5fcd0d
7 files changed
+282 -3

No files matched your search

+24
View File
@@ -0,0 +1,24 @@
#### Improve conditional type alias layout (#15811 by @seiyab)
<!-- prettier-ignore -->
```ts
// Input
type FallbackFlags<F extends Flags | undefined> =
Equals<NonNullableFlag<F>["flags"], {}> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];
// Prettier stable
type FallbackFlags<F extends Flags | undefined> = Equals<
NonNullableFlag<F>["flags"],
{}
> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];
// Prettier main
type FallbackFlags<F extends Flags | undefined> =
Equals<NonNullableFlag<F>["flags"], {}> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];
```
+28 -2
View File
@@ -25,6 +25,10 @@ import {
import { shouldInlineLogicalExpression } from "./binaryish.js";
import { printCallExpression } from "./call-expression.js";
/**
* @typedef {import("../../common/ast-path.js").default} AstPath
*/
function printAssignment(
path,
options,
@@ -147,7 +151,6 @@ function chooseLayout(path, options, print, leftDoc, rightPropertyName) {
if (
isComplexDestructuring(node) ||
isComplexTypeAliasParams(node) ||
hasComplexTypeAnnotation(node) ||
(isArrowFunctionVariableDeclarator(node) && canBreakLeftDoc)
) {
@@ -166,6 +169,10 @@ function chooseLayout(path, options, print, leftDoc, rightPropertyName) {
return "break-after-operator";
}
if (isComplexTypeAliasParams(node)) {
return "break-lhs";
}
if (
!canBreakLeftDoc &&
(hasShortKey ||
@@ -194,7 +201,10 @@ function shouldBreakAfterOperator(path, options, print, hasShortKey) {
return true;
case "TSConditionalType":
case "ConditionalTypeAnnotation":
if (!options.experimentalTernaries) {
if (
!options.experimentalTernaries &&
!shouldBreakBeforeConditionalType(rightNode)
) {
break;
}
return true;
@@ -435,6 +445,22 @@ function getTypeArgumentsFromCallExpression(node) {
return (node.typeParameters ?? node.typeArguments)?.params;
}
function shouldBreakBeforeConditionalType(node) {
function isGeneric(subNode) {
switch (subNode.type) {
case "FunctionTypeAnnotation":
case "GenericTypeAnnotation":
case "TSFunctionType":
case "TSTypeReference":
return Boolean(subNode.typeParameters);
default:
return false;
}
}
return isGeneric(node.checkType) || isGeneric(node.extendsType);
}
export {
isArrowFunctionVariableDeclarator,
printAssignment,
@@ -1,5 +1,89 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`conditional.js [babel-flow] format 1`] = `
"Unexpected token (2:43)
1 | type FallbackFlags<F: Flags | void> =
> 2 | Equals<NonNullableFlag<F>["flags"], {}> extends true
| ^
3 | ? Dict<any>
4 | : NonNullableFlag<F>["flags"];
5 |
Cause: Unexpected token (2:42)"
`;
exports[`conditional.js format 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80
| printWidth
=====================================input======================================
type FallbackFlags<F: Flags | void> =
Equals<NonNullableFlag<F>["flags"], {}> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];
export type UnPromise<Type: Promise<mixed>> =
Type extends Promise<infer Generic>
? Generic
: empty;
export type Equals<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2)
? true
: false;
export type _Repeat<A: any, N: number, L: List = []> =
__Repeat<N, A, L> extends infer X
? Cast<X, List>
: empty
export type Repeat<A: any, N: number, L: List = []> =
N extends mixed
? L extends mixed
? _Repeat<A, N, L>
: empty
: empty
export type Intersect<U1: any, U2: any> =
U1 extends mixed
? U2 extends mixed
? {1: U1, 0: empty}[Equals<U1, U2>]
: empty
: empty
=====================================output=====================================
type FallbackFlags<F: Flags | void> =
Equals<NonNullableFlag<F>["flags"], {}> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];
export type UnPromise<Type: Promise<mixed>> =
Type extends Promise<infer Generic> ? Generic : empty;
export type Equals<X, Y> =
(<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
? true
: false;
export type _Repeat<A: any, N: number, L: List = []> =
__Repeat<N, A, L> extends infer X ? Cast<X, List> : empty;
export type Repeat<A: any, N: number, L: List = []> = N extends mixed
? L extends mixed
? _Repeat<A, N, L>
: empty
: empty;
export type Intersect<U1: any, U2: any> = U1 extends mixed
? U2 extends mixed
? { 1: U1, 0: empty }[Equals<U1, U2>]
: empty
: empty;
================================================================================
`;
exports[`issue-100857.js format 1`] = `
====================================options=====================================
parsers: ["flow"]
@@ -0,0 +1,34 @@
type FallbackFlags<F: Flags | void> =
Equals<NonNullableFlag<F>["flags"], {}> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];
export type UnPromise<Type: Promise<mixed>> =
Type extends Promise<infer Generic>
? Generic
: empty;
export type Equals<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2)
? true
: false;
export type _Repeat<A: any, N: number, L: List = []> =
__Repeat<N, A, L> extends infer X
? Cast<X, List>
: empty
export type Repeat<A: any, N: number, L: List = []> =
N extends mixed
? L extends mixed
? _Repeat<A, N, L>
: empty
: empty
export type Intersect<U1: any, U2: any> =
U1 extends mixed
? U2 extends mixed
? {1: U1, 0: empty}[Equals<U1, U2>]
: empty
: empty
+5 -1
View File
@@ -1 +1,5 @@
run_spec(import.meta, ["flow"]);
run_spec(import.meta, ["flow"], {
errors: {
"babel-flow": ["conditional.js"],
},
});
@@ -1,5 +1,78 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`conditional.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
| printWidth
=====================================input======================================
type FallbackFlags<F extends Flags | undefined> =
Equals<NonNullableFlag<F>["flags"], {}> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];
export type UnPromise<Type extends Promise<unknown>> =
Type extends Promise<infer Generic>
? Generic
: never;
export type Equals<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2)
? true
: false;
export type _Repeat<A extends any, N extends number, L extends List = []> =
__Repeat<N, A, L> extends infer X
? Cast<X, List>
: never
export type Repeat<A extends any, N extends number, L extends List = []> =
N extends unknown
? L extends unknown
? _Repeat<A, N, L>
: never
: never
export type Intersect<U1 extends any, U2 extends any> =
U1 extends unknown
? U2 extends unknown
? {1: U1, 0: never}[Equals<U1, U2>]
: never
: never
=====================================output=====================================
type FallbackFlags<F extends Flags | undefined> =
Equals<NonNullableFlag<F>["flags"], {}> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];
export type UnPromise<Type extends Promise<unknown>> =
Type extends Promise<infer Generic> ? Generic : never;
export type Equals<X, Y> =
(<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
? true
: false;
export type _Repeat<A extends any, N extends number, L extends List = []> =
__Repeat<N, A, L> extends infer X ? Cast<X, List> : never;
export type Repeat<
A extends any,
N extends number,
L extends List = [],
> = N extends unknown ? (L extends unknown ? _Repeat<A, N, L> : never) : never;
export type Intersect<U1 extends any, U2 extends any> = U1 extends unknown
? U2 extends unknown
? { 1: U1; 0: never }[Equals<U1, U2>]
: never
: never;
================================================================================
`;
exports[`issue-9874.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -0,0 +1,34 @@
type FallbackFlags<F extends Flags | undefined> =
Equals<NonNullableFlag<F>["flags"], {}> extends true
? Dict<any>
: NonNullableFlag<F>["flags"];
export type UnPromise<Type extends Promise<unknown>> =
Type extends Promise<infer Generic>
? Generic
: never;
export type Equals<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2)
? true
: false;
export type _Repeat<A extends any, N extends number, L extends List = []> =
__Repeat<N, A, L> extends infer X
? Cast<X, List>
: never
export type Repeat<A extends any, N extends number, L extends List = []> =
N extends unknown
? L extends unknown
? _Repeat<A, N, L>
: never
: never
export type Intersect<U1 extends any, U2 extends any> =
U1 extends unknown
? U2 extends unknown
? {1: U1, 0: never}[Equals<U1, U2>]
: never
: never