evanw/esbuild · error · LexerPanic

Unexpected newline after "type"

Error message

Unexpected newline after "type"

What it means

In 'export type ...' (TypeScript), a newline immediately after 'type' is disallowed unless the next token is '{' or '*' (js_parser.go:7182). This guards against 'export\ntype' being misread as a type alias.

Source

Thrown at internal/js_parser/js_parser.go:7185

					p.log.AddError(&p.tracker, logger.Range{Loc: logger.Loc{Start: asyncRange.End()}},
						"Unexpected newline after \"async\"")
					panic(js_lexer.LexerPanic{})
				}
				p.lexer.Expect(js_lexer.TFunction)
				opts.isExport = true
				return p.parseFnStmt(loc, opts, true /* isAsync */, asyncRange)
			}

			if p.options.ts.Parse {
				switch p.lexer.Identifier.String {
				case "type":
					// "export type foo = ..."
					typeRange := p.lexer.Range()
					p.lexer.Next()
					if p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace && p.lexer.Token != js_lexer.TAsterisk {
						p.log.AddError(&p.tracker, logger.Range{Loc: logger.Loc{Start: typeRange.End()}},
							"Unexpected newline after \"type\"")
						panic(js_lexer.LexerPanic{})
					}
					p.skipTypeScriptTypeStmt(parseStmtOpts{isModuleScope: opts.isModuleScope, isExport: true})
					return js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}

				case "namespace", "abstract", "module", "interface":
					// "export namespace Foo {}"
					// "export abstract class Foo {}"
					// "export module Foo {}"
					// "export interface Foo {}"
					opts.isExport = true
					return p.parseStmt(opts)

				case "declare":
					// "export declare class Foo {}"
					opts.isExport = true
					opts.lexicalDecl = lexicalDeclAllowAll
					opts.isTypeScriptDeclare = true
					return p.parseStmt(opts)

View on GitHub (pinned to f6058f8364)

Solutions

  1. Put the type name on the same line as 'export type'.
  2. If you intended a namespace/type-group, follow 'type' with '{' on the same line.

Example fix

// before
export type
Foo = string
// after
export type Foo = string
Defensive patterns

Strategy: validation

Validate before calling

import "github.com/evanw/esbuild/pkg/api"
res := api.Transform(src, api.TransformOptions{Loader: api.LoaderTS})
for _, m := range res.Errors {
  if strings.Contains(m.Text, `Unexpected newline after "type"`) {
    // a line break sits after 'export type' before the type name
  }
}

Prevention

When it happens

Trigger: 'export type\nFoo = string' — a line break after 'type' not followed by '{' (namespace) or '*' (re-export all).

Common situations: Formatter wrapping 'export' and 'type' onto separate lines; refactor artifacts; confusion between 'export type' and a value export.

Related errors


AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09). Data as JSON: /api/errors/0a4a5270f719b252. Report an issue: GitHub.