microsoft / microsoft/TypeScript

Crash: class-level decorator on an anonymous class panics during ES decorator emit

Open
#63,962 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
132

Description

🔎 Search Terms

anonymous class decorator crash, "A class declaration that is not a default export must have a name", esDecorator visitClassDeclaration, ChildIsDecorated, typescript-go#3891, @dec class {}

🕗 Version & Regression Information
  • This is a crash
  • Also crashes TypeScript 6.0.3 (JS) with the same assert.
  • Reproduced on 7.1.0-dev (main) with emit and --target es2022 (also es5 / es2015 / es2021). --target esnext and --noEmit do not crash.
⏯ Playground Link

https://www.typescriptlang.org/play/?ts=6.0.0-dev.20260416#code/CYUwxgNghgTiAEA3W9RgFzygOwJ4G4AoAATUMigGdL4BvQgXyA

💻 Code
declare var dec: any;
@dec
class {
}
🙁 Actual behavior
panic: Debug failure. False expression: A class declaration that is not a default export must have a name. [recovered, repanicked]

goroutine 107 [running]:
sync.(*WaitGroup).Go.func1.1()
        sync/waitgroup.go:251 +0x48
panic({0x105ea58e0?, 0x11e74b992390?})
        runtime/panic.go:860 +0x12c
github.com/microsoft/TypeScript/tsc/internal/debug.Fail(...)
        github.com/microsoft/TypeScript/tsc/internal/debug/debug.go:14
github.com/microsoft/TypeScript/tsc/internal/debug.assertSlow(...)
        github.com/microsoft/TypeScript/tsc/internal/debug/debug.go:60 +0x5c
github.com/microsoft/TypeScript/tsc/internal/debug.Assert(...)
        github.com/microsoft/TypeScript/tsc/internal/debug/debug.go:49
github.com/microsoft/TypeScript/tsc/internal/transformers/estransforms.(*esDecoratorTransformer).visitClassDeclaration(...)
        github.com/microsoft/TypeScript/tsc/internal/transformers/estransforms/esdecorator.go:1071 +0x5ec
github.com/microsoft/TypeScript/tsc/internal/transformers/estransforms.(*esDecoratorTransformer).visit(...)
        github.com/microsoft/TypeScript/tsc/internal/transformers/estransforms/esdecorator.go:318 +0x35c
github.com/microsoft/TypeScript/tsc/internal/ast.(*NodeVisitor).VisitSlice(...)
        github.com/microsoft/TypeScript/tsc/internal/ast/visitor.go:148 +0xa0
github.com/microsoft/TypeScript/tsc/internal/ast.(*NodeVisitor).VisitNodes(...)
        github.com/microsoft/TypeScript/tsc/internal/ast/visitor.go:99 +0x3c
github.com/microsoft/TypeScript/tsc/internal/printer.(*EmitContext).VisitVariableEnvironment(...)
        github.com/microsoft/TypeScript/tsc/internal/printer/emitcontext.go:796 +0x17c
... 42 lines truncated ...
github.com/microsoft/TypeScript/tsc/internal/compiler.(*emitter).emitJSFile(...)
        github.com/microsoft/TypeScript/tsc/internal/compiler/emitter.go:200 +0x198
github.com/microsoft/TypeScript/tsc/internal/compiler.(*emitter).emit(...)
        github.com/microsoft/TypeScript/tsc/internal/compiler/emitter.go:50 +0xec
github.com/microsoft/TypeScript/tsc/internal/compiler.(*Program).Emit.func2()
        github.com/microsoft/TypeScript/tsc/internal/compiler/program.go:1851 +0x1c0
🙂 Expected behavior

The compiler should not crash 🙂

Additional information about the issue

Disclosure: This crash was found with a custom mutation fuzzer and AI assistance (Kimi K3). The input was minimized and then verified by hand against TypeScript 7.1.0-dev (main) and TypeScript 6.0.3.

This appears to be a leftover of the fix for typescript-go#3891 / typescript-go#3926 (commit 710928bdf2). That fix covers an anonymous class with a member decorator (class { @x m() {} }). It does not cover a class-level decorator (@dec class {}).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in internal/transformers/estransforms/esdecorator.go at visitClassDeclaration around the assertion shown in the stack trace. Reproduce the anonymous class with a class-level decorator using emit and an ES2022 target, then trace how the decorator transformer handles the missing class name. Done means the compiler no longer panics for this input and regression coverage verifies the behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, typescript
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.