Repository: babel/babel
File: packages/babel-generator/src/node/parentheses.ts (TypeScript)

Code before:
      parentType === "NewExpression" ||
      parentType === "TSInstantiationExpression") &&
    !!(process.env.BABEL_8_BREAKING
      ? // @ts-ignore(Babel 7 vs Babel 8) Babel 8 AST
        parent.typeArguments
      : // @ts-ignore(Babel 7 vs Babel 8) Babel 7 AST
        parent.typeParameters)
  );
}

export function TSFunctionType(
  node: t.TSFunctionType,
  parent: t.Node,
): boolean {
  const parentType = parent.type;
  return (
    parentType === "TSIntersectionType" ||
    parentType === "TSUnionType" ||
    parentType === "TSOptionalType" ||
    parentType === "TSArrayType" ||
    parentType === "TSIndexedAccessType" ||
    (parentType === "TSConditionalType" &&
      (parent.checkType === node || parent.extendsType === node))
  );
}

export function BinaryExpression(
  node: t.BinaryExpression,
  parent: t.Node,
  tokenContext: unknown,
  inForStatementInit: boolean,
): boolean {
  // for ((1 in []);;);
  // for (var x = (1 in []) in 2);
  return node.operator === "in" && inForStatementInit;
}

export function SequenceExpression(
  node: t.SequenceExpression,
  parent: t.Node,
): boolean {
  const parentType = parent.type;
  if (
    parentType === "SequenceExpression" ||
    parentType === "ParenthesizedExpression" ||
    (parentType === "MemberExpression" && parent.property === node) ||
    (parentType === "OptionalMemberExpression" && parent.property === node) ||
    parentType === "TemplateLiteral"
  ) {
    return false;
  }

Review comment (refactor):
We should handle `TSConstructorType` such as `new () => Date` or `abstract new () => Date` as well.

Code after:
      parentType === "NewExpression" ||
      parentType === "TSInstantiationExpression") &&
    !!(process.env.BABEL_8_BREAKING
      ? // @ts-ignore(Babel 7 vs Babel 8) Babel 8 AST
        parent.typeArguments
      : // @ts-ignore(Babel 7 vs Babel 8) Babel 7 AST
        parent.typeParameters)
  );
}

export function TSFunctionType(
  node: t.TSFunctionType,
  parent: t.Node,
): boolean {
  const parentType = parent.type;
  return (
    parentType === "TSIntersectionType" ||
    parentType === "TSUnionType" ||
    parentType === "TSOptionalType" ||
    parentType === "TSArrayType" ||
    (parentType === "TSIndexedAccessType" && parent.objectType === node) ||
    (parentType === "TSConditionalType" &&
      (parent.checkType === node || parent.extendsType === node))
  );
}

export { TSFunctionType as TSConstructorType };

export function BinaryExpression(
  node: t.BinaryExpression,
  parent: t.Node,
  tokenContext: unknown,
  inForStatementInit: boolean,
): boolean {
  // for ((1 in []);;);
  // for (var x = (1 in []) in 2);
  return node.operator === "in" && inForStatementInit;
}

export function SequenceExpression(
  node: t.SequenceExpression,
  parent: t.Node,
): boolean {
  const parentType = parent.type;
  if (
    parentType === "SequenceExpression" ||
    parentType === "ParenthesizedExpression" ||
    (parentType === "MemberExpression" && parent.property === node) ||
    (parentType === "OptionalMemberExpression" && parent.property === node) ||
    parentType === "TemplateLiteral"
  ) {