Skip to content

fix(isolated_declarations): collect types from private accessors for paired inference#21516

Merged
graphite-app[bot] merged 1 commit intomainfrom
fix/isolated-declarations-accessor-pair-private-setter
Apr 20, 2026
Merged

fix(isolated_declarations): collect types from private accessors for paired inference#21516
graphite-app[bot] merged 1 commit intomainfrom
fix/isolated-declarations-accessor-pair-private-setter

Conversation

@Dunqing
Copy link
Copy Markdown
Member

@Dunqing Dunqing commented Apr 17, 2026

Summary

A public (or protected) getter paired with a private set(v: T) should get its return type from the setter's parameter annotation — that's the standard isolatedDeclarations accessor-pair inference rule ("one annotated side is enough"). Previously, collect_accessor_annotations skipped any accessor with a private modifier, so the pairing never happened and TS9009 fired on the untyped getter.

This change:

  • No longer skips private-modifier accessors when collecting annotations for paired inference.
  • For private setters, collects the explicit parameter type annotation — same behavior as before for non-private setters (no body inference).
  • For private getters, only uses an explicit return type annotation. Running body inference would surface errors like TS9038 on the private accessor's body, which is irrelevant because the private accessor is emitted as a type-erased class member anyway.

Example

export class MockProxy {
  get isRunning() {
    return this._state.isRunning;
  }

  private set isRunning(val: boolean) {
    this._state.isRunning = val;
  }
}

Before: TS9009: At least one accessor must have an explicit return type annotation.
After: no error — emits get isRunning(): boolean; and private set isRunning(value);, matching tsc.

Test plan

  • Added fixtures for both a public getter + private setter pair and a protected getter + private setter pair
  • cargo test -p oxc_isolated_declarations — no regression on existing private-accessor snapshots

Closes #21503 (case 2)

@Dunqing Dunqing changed the title fix(linter/unicorn): handle computed property access in prefer-dom-node-remove rule (#21470) fix(isolated_declarations): collect types from private accessors for paired inference Apr 17, 2026
Copy link
Copy Markdown
Member Author

Dunqing commented Apr 17, 2026


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent changes, fast-track this PR to the front of the merge queue

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions github-actions Bot added A-isolated-declarations Isolated Declarations C-bug Category - Bug labels Apr 17, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 17, 2026

Merging this PR will not alter performance

✅ 44 untouched benchmarks
⏩ 7 skipped benchmarks1


Comparing fix/isolated-declarations-accessor-pair-private-setter (b1b017a) with main (80339dd)

Open in CodSpeed

Footnotes

  1. 7 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@Dunqing Dunqing force-pushed the fix/isolated-declarations-accessor-pair-private-setter branch from 77c7813 to b1b017a Compare April 17, 2026 06:19
@Dunqing Dunqing marked this pull request as ready for review April 17, 2026 06:41
@Dunqing Dunqing added the 0-merge Merge with Graphite Merge Queue label Apr 20, 2026
Copy link
Copy Markdown
Member Author

Dunqing commented Apr 20, 2026

Merge activity

  • Apr 20, 2:19 AM UTC: The merge label '0-merge' was detected. This PR will be added to the Graphite merge queue once it meets the requirements.
  • Apr 20, 2:19 AM UTC: Dunqing added this pull request to the Graphite merge queue.
  • Apr 20, 2:25 AM UTC: The Graphite merge queue couldn't merge this PR because it was not satisfying all requirements (Failed CI: 'Test NAPI Compiler').
  • Apr 20, 4:37 AM UTC: The merge label '0-merge' was detected. This PR will be added to the Graphite merge queue once it meets the requirements.
  • Apr 20, 4:37 AM UTC: Dunqing added this pull request to the Graphite merge queue.
  • Apr 20, 5:04 AM UTC: Merged by the Graphite merge queue.

graphite-app Bot pushed a commit that referenced this pull request Apr 20, 2026
…paired inference (#21516)

## Summary

A public (or protected) getter paired with a `private set(v: T)` should get its return type from the setter's parameter annotation — that's the standard `isolatedDeclarations` accessor-pair inference rule ("one annotated side is enough"). Previously, `collect_accessor_annotations` skipped any accessor with a `private` modifier, so the pairing never happened and `TS9009` fired on the untyped getter.

This change:

- No longer skips `private`-modifier accessors when collecting annotations for paired inference.
- For private **setters**, collects the explicit parameter type annotation — same behavior as before for non-private setters (no body inference).
- For private **getters**, only uses an explicit return type annotation. Running body inference would surface errors like `TS9038` on the private accessor's body, which is irrelevant because the private accessor is emitted as a type-erased class member anyway.

## Example

```ts
export class MockProxy {
  get isRunning() {
    return this._state.isRunning;
  }

  private set isRunning(val: boolean) {
    this._state.isRunning = val;
  }
}
```

Before: `TS9009: At least one accessor must have an explicit return type annotation`.
After: no error — emits `get isRunning(): boolean;` and `private set isRunning(value);`, matching tsc.

## Test plan

- [x] Added fixtures for both a public getter + private setter pair and a protected getter + private setter pair
- [x] `cargo test -p oxc_isolated_declarations` — no regression on existing private-accessor snapshots

Closes #21503 (case 2)
@graphite-app graphite-app Bot force-pushed the fix/isolated-declarations-accessor-pair-private-setter branch from b1b017a to 811876a Compare April 20, 2026 02:20
@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label Apr 20, 2026
@Dunqing Dunqing added the 0-merge Merge with Graphite Merge Queue label Apr 20, 2026
graphite-app Bot pushed a commit that referenced this pull request Apr 20, 2026
…paired inference (#21516)

## Summary

A public (or protected) getter paired with a `private set(v: T)` should get its return type from the setter's parameter annotation — that's the standard `isolatedDeclarations` accessor-pair inference rule ("one annotated side is enough"). Previously, `collect_accessor_annotations` skipped any accessor with a `private` modifier, so the pairing never happened and `TS9009` fired on the untyped getter.

This change:

- No longer skips `private`-modifier accessors when collecting annotations for paired inference.
- For private **setters**, collects the explicit parameter type annotation — same behavior as before for non-private setters (no body inference).
- For private **getters**, only uses an explicit return type annotation. Running body inference would surface errors like `TS9038` on the private accessor's body, which is irrelevant because the private accessor is emitted as a type-erased class member anyway.

## Example

```ts
export class MockProxy {
  get isRunning() {
    return this._state.isRunning;
  }

  private set isRunning(val: boolean) {
    this._state.isRunning = val;
  }
}
```

Before: `TS9009: At least one accessor must have an explicit return type annotation`.
After: no error — emits `get isRunning(): boolean;` and `private set isRunning(value);`, matching tsc.

## Test plan

- [x] Added fixtures for both a public getter + private setter pair and a protected getter + private setter pair
- [x] `cargo test -p oxc_isolated_declarations` — no regression on existing private-accessor snapshots

Closes #21503 (case 2)
@graphite-app graphite-app Bot force-pushed the fix/isolated-declarations-accessor-pair-private-setter branch from 811876a to 92c70bc Compare April 20, 2026 04:38
graphite-app Bot pushed a commit that referenced this pull request Apr 20, 2026
…paired inference (#21516)

## Summary

A public (or protected) getter paired with a `private set(v: T)` should get its return type from the setter's parameter annotation — that's the standard `isolatedDeclarations` accessor-pair inference rule ("one annotated side is enough"). Previously, `collect_accessor_annotations` skipped any accessor with a `private` modifier, so the pairing never happened and `TS9009` fired on the untyped getter.

This change:

- No longer skips `private`-modifier accessors when collecting annotations for paired inference.
- For private **setters**, collects the explicit parameter type annotation — same behavior as before for non-private setters (no body inference).
- For private **getters**, only uses an explicit return type annotation. Running body inference would surface errors like `TS9038` on the private accessor's body, which is irrelevant because the private accessor is emitted as a type-erased class member anyway.

## Example

```ts
export class MockProxy {
  get isRunning() {
    return this._state.isRunning;
  }

  private set isRunning(val: boolean) {
    this._state.isRunning = val;
  }
}
```

Before: `TS9009: At least one accessor must have an explicit return type annotation`.
After: no error — emits `get isRunning(): boolean;` and `private set isRunning(value);`, matching tsc.

## Test plan

- [x] Added fixtures for both a public getter + private setter pair and a protected getter + private setter pair
- [x] `cargo test -p oxc_isolated_declarations` — no regression on existing private-accessor snapshots

Closes #21503 (case 2)
@graphite-app graphite-app Bot force-pushed the fix/isolated-declarations-accessor-pair-private-setter branch from 92c70bc to c05af7a Compare April 20, 2026 04:45
graphite-app Bot pushed a commit that referenced this pull request Apr 20, 2026
…paired inference (#21516)

## Summary

A public (or protected) getter paired with a `private set(v: T)` should get its return type from the setter's parameter annotation — that's the standard `isolatedDeclarations` accessor-pair inference rule ("one annotated side is enough"). Previously, `collect_accessor_annotations` skipped any accessor with a `private` modifier, so the pairing never happened and `TS9009` fired on the untyped getter.

This change:

- No longer skips `private`-modifier accessors when collecting annotations for paired inference.
- For private **setters**, collects the explicit parameter type annotation — same behavior as before for non-private setters (no body inference).
- For private **getters**, only uses an explicit return type annotation. Running body inference would surface errors like `TS9038` on the private accessor's body, which is irrelevant because the private accessor is emitted as a type-erased class member anyway.

## Example

```ts
export class MockProxy {
  get isRunning() {
    return this._state.isRunning;
  }

  private set isRunning(val: boolean) {
    this._state.isRunning = val;
  }
}
```

Before: `TS9009: At least one accessor must have an explicit return type annotation`.
After: no error — emits `get isRunning(): boolean;` and `private set isRunning(value);`, matching tsc.

## Test plan

- [x] Added fixtures for both a public getter + private setter pair and a protected getter + private setter pair
- [x] `cargo test -p oxc_isolated_declarations` — no regression on existing private-accessor snapshots

Closes #21503 (case 2)
@graphite-app graphite-app Bot force-pushed the fix/isolated-declarations-accessor-pair-private-setter branch from c05af7a to db81c89 Compare April 20, 2026 04:46
…paired inference (#21516)

## Summary

A public (or protected) getter paired with a `private set(v: T)` should get its return type from the setter's parameter annotation — that's the standard `isolatedDeclarations` accessor-pair inference rule ("one annotated side is enough"). Previously, `collect_accessor_annotations` skipped any accessor with a `private` modifier, so the pairing never happened and `TS9009` fired on the untyped getter.

This change:

- No longer skips `private`-modifier accessors when collecting annotations for paired inference.
- For private **setters**, collects the explicit parameter type annotation — same behavior as before for non-private setters (no body inference).
- For private **getters**, only uses an explicit return type annotation. Running body inference would surface errors like `TS9038` on the private accessor's body, which is irrelevant because the private accessor is emitted as a type-erased class member anyway.

## Example

```ts
export class MockProxy {
  get isRunning() {
    return this._state.isRunning;
  }

  private set isRunning(val: boolean) {
    this._state.isRunning = val;
  }
}
```

Before: `TS9009: At least one accessor must have an explicit return type annotation`.
After: no error — emits `get isRunning(): boolean;` and `private set isRunning(value);`, matching tsc.

## Test plan

- [x] Added fixtures for both a public getter + private setter pair and a protected getter + private setter pair
- [x] `cargo test -p oxc_isolated_declarations` — no regression on existing private-accessor snapshots

Closes #21503 (case 2)
@graphite-app graphite-app Bot force-pushed the fix/isolated-declarations-accessor-pair-private-setter branch from db81c89 to 065ce47 Compare April 20, 2026 04:51
@graphite-app graphite-app Bot merged commit 065ce47 into main Apr 20, 2026
27 checks passed
@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label Apr 20, 2026
@graphite-app graphite-app Bot deleted the fix/isolated-declarations-accessor-pair-private-setter branch April 20, 2026 05:04
camc314 added a commit that referenced this pull request Apr 20, 2026
### 🐛 Bug Fixes

- 48967e8 isolated_declarations: Drop required type check for private
parameter properties on private constructors (#21515) (Dunqing)
- 91e5bde transformer/typescript: Preserve computed-key static block
when class has an empty constructor (#21562) (Dunqing)
- 50e9d26 mangler: Assign correct slot to shadowed function-expression
names (#21535) (Dunqing)
- 065ce47 isolated_declarations: Collect types from private accessors
for paired inference (#21516) (Dunqing)
- 00fc136 codegen: Preserve coverage comments before object properties
(#21312) (bab)
- d676e0c minifier: Mark LHS of `??=` as read when converting from `==
null &&` (#21546) (Gunnlaugur Thor Briem)

### ⚡ Performance

- e45efc5 parser: Reduce `try_parse` usage in favour of `lookahead`
(#21532) (Boshen)
- ddb1bf8 parser: Avoid redundant `IdentifierReference` clone in
shorthand property (#21511) (Boshen)
- be2b392 allocator: Store pointers directly in `Arena` (#21483)
(overlookmotel)

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Co-authored-by: Cameron <cameron.clark@hey.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-isolated-declarations Isolated Declarations C-bug Category - Bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isolatedDeclarations: oxc is stricter than tsc for inferred accessor return types and constructor parameter defaults

1 participant