Summary
An anonymous default class with a heritage clause loses the clause and its members:
class Base { b = 1 }
export default class extends Base { c = 2 }emits export default class extends {}, which does not parse, and export default class implements Reporter {} (knip's playwright reporter fixture) emits export default class implements {}.
Changes
extractClass read extends or implements as the class name. Now extends, or implements followed by a type, begins the heritage clause of an anonymous default class, the same way TypeScript reads it. The class is named __dtsx_default_class__, a helper name the file does not use, as a default-exported expression gets __dtsx_default_export__. A plain AnonymousClass could collide with a real class of that name, in the file or in a bundle. Everything else is read as before, including a class named implements and an anonymous generic class (AnonymousClass<T>).
Testing
New test/anonymous-default-class.test.ts, with each case type-checked through a consumer using the existing runTsc helper:
extends,implements,abstractwithimplements, generic withextends;- beside a real
AnonymousClass; - a two-file
generate({ bundle: true })whose other file exportsAnonymousClassand a template literal type spelling it; - two classes named
implements, which must stay as they are.
On main the 3 heritage cases, the collision case and the bundle case fail.
bun test (Zig library built with the pinned Zig, so its tests run too), typecheck, lint and zig build test pass. Over 4,192 files from vue-core, vue-router, pinia and knip (LF and CRLF), the only output that changes is knip's playwright fixture, which now parses. Over 11,774 more from tailwindcss, stacks, eslint-plugin-vue and home, nothing changes.