ReviewOS

also looking at this

stacks/dtsx

fix(extractor): keep a protected constructor protected

#3125
Open mkantautas wants to merge fix/protected-constructor into main
2 files +77 -2
8 days ago

Summary

A protected constructor is emitted as a public one:

export class Singleton {
  protected constructor(name: string) {}
  static create(): Singleton { return new Singleton('x') }
}

emits constructor(name: string);, so new Singleton('x') type-checks against the declarations although only the class and its subclasses may construct it. tsc emits protected constructor(name: string);. Home's bundled bun-debug-adapter-protocol (protected constructor(inspector: T, ...)) comes out this way.

Changes

buildClassBodyDts reads the protected modifier for every member but dropped it when it emitted the constructor. It now keeps it, as it does for methods, when protected stands on the same line as constructor. After a line break, protected is a field of that name and the constructor stays public, as TypeScript reads it.

Testing

New test/protected-constructor.test.ts, each case type-checked through a consumer with the existing runTsc helper. A plain protected constructor, one with a parameter property, and overloads must reject new from outside (@ts-expect-error) while a subclass constructs normally; on main these 3 fail. A public constructor, a field named protected on the line before constructor, and a line break inside a comment after protected must stay public.

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) nothing changes. Over 11,774 more from tailwindcss, stacks, eslint-plugin-vue and home, the only change is the home file above, whose constructor is now protected.

2 changed files on the files tab, with 0 review threads.

Sign in to comment on this pull request.