TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

Manually constructed nullish coalescing AST is missing parentheses when printed

Open mmalerba opened this issue 10 months ago • 0 comments

🔎 Search Terms

nullish coalescing parentheses ast

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about nullish coalescing

⏯ Playground Link

https://stackblitz.com/edit/vitejs-vite-letuvqes?file=src%2Fmain.ts

💻 Code

import * as ts from 'typescript';

const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
const src = ts.createSourceFile('test.ts', '', ts.ScriptTarget.Latest);

const nullishNode = ts.factory.createExpressionStatement(
  ts.factory.createBinaryExpression(
    ts.factory.createConditionalExpression(
      ts.factory.createIdentifier('a'),
      ts.factory.createToken(ts.SyntaxKind.QuestionToken),
      ts.factory.createIdentifier('b'),
      ts.factory.createToken(ts.SyntaxKind.ColonToken),
      ts.factory.createIdentifier('c')
    ),
    ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
    ts.factory.createIdentifier('d')
  )
);

const orNode = ts.factory.createExpressionStatement(
  ts.factory.createBinaryExpression(
    ts.factory.createConditionalExpression(
      ts.factory.createIdentifier('a'),
      ts.factory.createToken(ts.SyntaxKind.QuestionToken),
      ts.factory.createIdentifier('b'),
      ts.factory.createToken(ts.SyntaxKind.ColonToken),
      ts.factory.createIdentifier('c')
    ),
    ts.factory.createToken(ts.SyntaxKind.BarBarToken),
    ts.factory.createIdentifier('d')
  )
);

// a ? b : c ?? d
const nullish = printer.printNode(ts.EmitHint.Unspecified, nullishNode, src);
// (a ? b : c) || d
const or = printer.printNode(ts.EmitHint.Unspecified, orNode, src);

🙁 Actual behavior

When I manually create AST for the expression (a ? b : c) ?? d but leave the parentheses out of the AST, the generated code does not add the parens back in and therefore does not match the structure of the AST.

When I do this same thing with || or && it behaves as expected, inserting the parens back in to the generated code.

🙂 Expected behavior

The nullishNode should be printed in the same way the orNode is in the example, adding back in the parentheses so that the code matches the structure of the AST

Additional information about the issue

No response

mmalerba avatar Mar 07 '25 01:03 mmalerba