diff --git a/internal/ast/precedence.go b/internal/ast/precedence.go index abeb9a57e2..26b001d362 100644 --- a/internal/ast/precedence.go +++ b/internal/ast/precedence.go @@ -414,6 +414,12 @@ const ( // TypePrecedenceConditional TypePrecedence = iota + // JSDoc precedence (optional and variadic types) + // + // JSDocType: + // `...`? Type `=`? + TypePrecedenceJSDoc + // Function precedence // // Type[Extends]: @@ -651,6 +657,8 @@ func GetTypeNodePrecedence(n *TypeNode) TypePrecedence { switch n.Kind { case KindConditionalType: return TypePrecedenceConditional + case KindJSDocOptionalType, KindJSDocVariadicType: + return TypePrecedenceJSDoc case KindFunctionType, KindConstructorType: return TypePrecedenceFunction case KindUnionType: @@ -684,6 +692,9 @@ func GetTypeNodePrecedence(n *TypeNode) TypePrecedence { KindObjectKeyword, KindIntrinsicKeyword, KindVoidKeyword, + KindJSDocAllType, + KindJSDocNullableType, + KindJSDocNonNullableType, KindLiteralType, KindTypePredicate, KindTypeReference, diff --git a/internal/printer/printer.go b/internal/printer/printer.go index 567b63fa76..d63d5c440a 100644 --- a/internal/printer/printer.go +++ b/internal/printer/printer.go @@ -2258,13 +2258,16 @@ func (p *Printer) emitTypeNode(node *ast.TypeNode, precedence ast.TypePrecedence // !!! Should this actually be considered a type? p.emitExpressionWithTypeArguments(node.AsExpressionWithTypeArguments()) - case ast.KindJSDocAllType, - ast.KindJSDocNullableType, - ast.KindJSDocNonNullableType, - ast.KindJSDocOptionalType, - ast.KindJSDocVariadicType: - // TODO - panic("not implemented") + case ast.KindJSDocAllType: + p.emitJSDocAllType(node) + case ast.KindJSDocNonNullableType: + p.emitJSDocNonNullableType(node.AsJSDocNonNullableType()) + case ast.KindJSDocNullableType: + p.emitJSDocNullableType(node.AsJSDocNullableType()) + case ast.KindJSDocOptionalType: + p.emitJSDocOptionalType(node.AsJSDocOptionalType()) + case ast.KindJSDocVariadicType: + p.emitJSDocVariadicType(node.AsJSDocVariadicType()) default: panic(fmt.Sprintf("unhandled TypeNode: %v", node.Kind)) @@ -2317,6 +2320,38 @@ func (p *Printer) emitBindingElementNode(node *ast.BindingElementNode) { p.emitBindingElement(node.AsBindingElement()) } +func (p *Printer) emitJSDocAllType(node *ast.Node) { + p.emitKeywordNode(node) +} + +func (p *Printer) emitJSDocNonNullableType(node *ast.JSDocNonNullableType) { + state := p.enterNode(node.AsNode()) + p.writePunctuation("!") + p.emitTypeNode(node.Type, ast.TypePrecedenceNonArray) + p.exitNode(node.AsNode(), state) +} + +func (p *Printer) emitJSDocNullableType(node *ast.JSDocNullableType) { + state := p.enterNode(node.AsNode()) + p.writePunctuation("?") + p.emitTypeNode(node.Type, ast.TypePrecedenceNonArray) + p.exitNode(node.AsNode(), state) +} + +func (p *Printer) emitJSDocOptionalType(node *ast.JSDocOptionalType) { + state := p.enterNode(node.AsNode()) + p.emitTypeNode(node.Type, ast.TypePrecedenceJSDoc) + p.writePunctuation("=") + p.exitNode(node.AsNode(), state) +} + +func (p *Printer) emitJSDocVariadicType(node *ast.JSDocVariadicType) { + state := p.enterNode(node.AsNode()) + p.writePunctuation("...") + p.emitTypeNode(node.Type, ast.TypePrecedenceJSDoc) + p.exitNode(node.AsNode(), state) +} + // // Expressions //