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
- Put the type name on the same line as 'export type'.
- 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
- Keep the type name on the same line as 'export type'.
- Validate TypeScript with tsc before bundling.
- Review formatter settings that wrap 'export type' declarations.
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
- Unexpected "interface"
- Unexpected newline after "async"
- Unexpected newline before "=>"
- Unexpected ":"
- For loop initializers cannot start with "async of"
AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09).
Data as JSON: /api/errors/0a4a5270f719b252.
Report an issue: GitHub.