Inline | null and | void (#1734)
TypeScript doesn't have the concept of `?` for nullable options and instead you have to write `| null` and `| void`. This is annoying to have it use the long form, so we're now inlining them. While working on this, I found out a few issues with the way we deal with those: - We only align objects if the parent is a union. This means that if you have `Array<{ object }>`, the object is not aligned properly. The fix is to move the alignment logic to the union, and not the child. - When doing so, it messes up with the comment alignment, so we have to manually handle children comment printing in the union code. It doesn't yet fix #1727 because the hardcoded type names are different, i'll follow up in a PR.master
parent
62679f20f0
commit
fe49650700
|
@ -817,7 +817,7 @@ function genericPrintNoParens(path, options, print, args) {
|
||||||
const leftBrace = n.exact ? "{|" : "{";
|
const leftBrace = n.exact ? "{|" : "{";
|
||||||
const rightBrace = n.exact ? "|}" : "}";
|
const rightBrace = n.exact ? "|}" : "}";
|
||||||
const parent = path.getParentNode(0);
|
const parent = path.getParentNode(0);
|
||||||
const parentIsUnionTypeAnnotation = parent.type === "UnionTypeAnnotation";
|
|
||||||
let propertiesField;
|
let propertiesField;
|
||||||
|
|
||||||
if (n.type === "TSTypeLiteral") {
|
if (n.type === "TSTypeLiteral") {
|
||||||
|
@ -881,10 +881,7 @@ function genericPrintNoParens(path, options, print, args) {
|
||||||
content = concat([
|
content = concat([
|
||||||
leftBrace,
|
leftBrace,
|
||||||
indent(
|
indent(
|
||||||
align(
|
|
||||||
parentIsUnionTypeAnnotation ? 2 : 0,
|
|
||||||
concat([options.bracketSpacing ? line : softline, concat(props)])
|
concat([options.bracketSpacing ? line : softline, concat(props)])
|
||||||
)
|
|
||||||
),
|
),
|
||||||
ifBreak(
|
ifBreak(
|
||||||
canHaveTrailingSeparator &&
|
canHaveTrailingSeparator &&
|
||||||
|
@ -892,10 +889,7 @@ function genericPrintNoParens(path, options, print, args) {
|
||||||
? separator
|
? separator
|
||||||
: ""
|
: ""
|
||||||
),
|
),
|
||||||
align(
|
concat([options.bracketSpacing ? line : softline, rightBrace]),
|
||||||
parentIsUnionTypeAnnotation ? 2 : 0,
|
|
||||||
concat([options.bracketSpacing ? line : softline, rightBrace])
|
|
||||||
),
|
|
||||||
n.typeAnnotation ? ": " : "",
|
n.typeAnnotation ? ": " : "",
|
||||||
path.call(print, "typeAnnotation")
|
path.call(print, "typeAnnotation")
|
||||||
]);
|
]);
|
||||||
|
@ -910,7 +904,7 @@ function genericPrintNoParens(path, options, print, args) {
|
||||||
parent &&
|
parent &&
|
||||||
shouldHugArguments(parent) &&
|
shouldHugArguments(parent) &&
|
||||||
parent.params[0] === n) ||
|
parent.params[0] === n) ||
|
||||||
(n.type === "ObjectTypeAnnotation" &&
|
(shouldHugType(n) &&
|
||||||
parentParentParent &&
|
parentParentParent &&
|
||||||
shouldHugArguments(parentParentParent) &&
|
shouldHugArguments(parentParentParent) &&
|
||||||
parentParentParent.params[0].typeAnnotation.typeAnnotation === n)
|
parentParentParent.params[0].typeAnnotation.typeAnnotation === n)
|
||||||
|
@ -1994,10 +1988,31 @@ function genericPrintNoParens(path, options, print, args) {
|
||||||
!(parent.type === "TypeAlias" &&
|
!(parent.type === "TypeAlias" &&
|
||||||
hasLeadingOwnLineComment(options.originalText, n));
|
hasLeadingOwnLineComment(options.originalText, n));
|
||||||
|
|
||||||
//const token = isIntersection ? "&" : "|";
|
// {
|
||||||
|
// a: string
|
||||||
|
// } | null | void
|
||||||
|
// should be inlined and not be printed in the multi-line variant
|
||||||
|
const shouldHug = shouldHugType(n);
|
||||||
|
|
||||||
|
// We want to align the children but without its comment, so it looks like
|
||||||
|
// | child1
|
||||||
|
// // comment
|
||||||
|
// | child2
|
||||||
|
const printed = path.map(typePath => {
|
||||||
|
let printedType = typePath.call(print);
|
||||||
|
if (!shouldHug && shouldIndent) {
|
||||||
|
printedType = align(2, printedType);
|
||||||
|
}
|
||||||
|
return comments.printComments(typePath, () => printedType, options);
|
||||||
|
}, "types");
|
||||||
|
|
||||||
|
if (shouldHug) {
|
||||||
|
return join(" | ", printed);
|
||||||
|
}
|
||||||
|
|
||||||
const code = concat([
|
const code = concat([
|
||||||
ifBreak(concat([shouldIndent ? line : "", "| "])),
|
ifBreak(concat([shouldIndent ? line : "", "| "])),
|
||||||
join(concat([line, "| "]), path.map(print, "types"))
|
join(concat([line, "| "]), printed)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return group(shouldIndent ? indent(code) : code);
|
return group(shouldIndent ? indent(code) : code);
|
||||||
|
@ -3341,7 +3356,7 @@ function printTypeParameters(path, options, print, paramsKey) {
|
||||||
|
|
||||||
const shouldInline =
|
const shouldInline =
|
||||||
n[paramsKey].length === 1 &&
|
n[paramsKey].length === 1 &&
|
||||||
(n[paramsKey][0].type === "ObjectTypeAnnotation" ||
|
(shouldHugType(n[paramsKey][0]) ||
|
||||||
n[paramsKey][0].type === "NullableTypeAnnotation");
|
n[paramsKey][0].type === "NullableTypeAnnotation");
|
||||||
|
|
||||||
if (shouldInline) {
|
if (shouldInline) {
|
||||||
|
@ -4479,6 +4494,25 @@ function isNodeStartingWithDeclare(node, options) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function shouldHugType(node) {
|
||||||
|
if (node.type === "ObjectTypeAnnotation") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.type === "UnionTypeAnnotation") {
|
||||||
|
const count = node.types.filter(
|
||||||
|
n =>
|
||||||
|
n.type === "VoidTypeAnnotation" ||
|
||||||
|
n.type === "NullLiteralTypeAnnotation"
|
||||||
|
).length;
|
||||||
|
|
||||||
|
if (node.types.length - 1 === count) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function shouldHugArguments(fun) {
|
function shouldHugArguments(fun) {
|
||||||
return (
|
return (
|
||||||
fun &&
|
fun &&
|
||||||
|
@ -4489,10 +4523,9 @@ function shouldHugArguments(fun) {
|
||||||
(fun.params[0].type === "Identifier" &&
|
(fun.params[0].type === "Identifier" &&
|
||||||
fun.params[0].typeAnnotation &&
|
fun.params[0].typeAnnotation &&
|
||||||
fun.params[0].typeAnnotation.type === "TypeAnnotation" &&
|
fun.params[0].typeAnnotation.type === "TypeAnnotation" &&
|
||||||
fun.params[0].typeAnnotation.typeAnnotation.type ===
|
shouldHugType(fun.params[0].typeAnnotation.typeAnnotation)) ||
|
||||||
"ObjectTypeAnnotation") ||
|
|
||||||
(fun.params[0].type === "FunctionTypeParam" &&
|
(fun.params[0].type === "FunctionTypeParam" &&
|
||||||
fun.params[0].typeAnnotation.type === "ObjectTypeAnnotation")) &&
|
shouldHugType(fun.params[0].typeAnnotation))) &&
|
||||||
!fun.rest
|
!fun.rest
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4557,8 +4590,13 @@ function printAstToDoc(ast, options, addAlignmentSize) {
|
||||||
|
|
||||||
function printGenerically(path, args) {
|
function printGenerically(path, args) {
|
||||||
const node = path.getValue();
|
const node = path.getValue();
|
||||||
|
const parent = path.getParentNode(0);
|
||||||
// We let JSXElement print its comments itself because it adds () around
|
// We let JSXElement print its comments itself because it adds () around
|
||||||
if (node && node.type === "JSXElement") {
|
// UnionTypeAnnotation has to align the child without the comments
|
||||||
|
if (
|
||||||
|
(node && node.type === "JSXElement") ||
|
||||||
|
(parent && parent.type === "UnionTypeAnnotation")
|
||||||
|
) {
|
||||||
return genericPrint(path, options, printGenerically, args);
|
return genericPrint(path, options, printGenerically, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`union.js 1`] = `
|
||||||
|
interface RelayProps {
|
||||||
|
articles: Array<{
|
||||||
|
__id: string,
|
||||||
|
} | null> | null | void | 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RelayProps {
|
||||||
|
articles: Array<{
|
||||||
|
__id: string,
|
||||||
|
} | null> | null | void,
|
||||||
|
}
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
interface RelayProps {
|
||||||
|
articles:
|
||||||
|
| Array<{
|
||||||
|
__id: string
|
||||||
|
} | null>
|
||||||
|
| null
|
||||||
|
| void
|
||||||
|
| 1
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RelayProps {
|
||||||
|
articles: Array<{
|
||||||
|
__id: string
|
||||||
|
} | null> | null | void
|
||||||
|
}
|
||||||
|
|
||||||
|
`;
|
|
@ -0,0 +1 @@
|
||||||
|
run_spec(__dirname, null, ["babylon"]);
|
|
@ -0,0 +1,11 @@
|
||||||
|
interface RelayProps {
|
||||||
|
articles: Array<{
|
||||||
|
__id: string,
|
||||||
|
} | null> | null | void | 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RelayProps {
|
||||||
|
articles: Array<{
|
||||||
|
__id: string,
|
||||||
|
} | null> | null | void,
|
||||||
|
}
|
Loading…
Reference in New Issue