Repository: TypeScript
Issue: A function that returns a class with a property getter is unusable via a declaration file (TS2611)
Labels: Needs Investigation,Fix Available,Rescheduled

# Bug Report

<!--
  Please fill in each section completely. Thank you!
-->

### 🔎 Search Terms

<!--
  What search terms did you use when trying to find an existing bug report?
  List them here so people in the future can find this one more easily.
-->

TS2611, declaration file, property getter

### 🕗 Version & Regression Information

<!-- When did you start seeing this bug occur?

"Bugs" that have existed in TS for a long time are very likely to be FAQs; refer to
  https://github.com/Microsoft/TypeScript/wiki/FAQ#common-bugs-that-arent-bugs

If possible, please try testing the nightly version of TS to see if it's already been fixed.
For npm: `typescript@next`
This is also the 'Nightly' version in the playground: http://www.typescriptlang.org/play/?ts=Nightly

Note: The TypeScript Playground can be used to try older versions of TypeScript.

Please keep and fill in the line that best applies:
-->
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about TS2611, declaration files, property getters

### ⏯ Playground Link

<!--
  A link to a TypeScript Playground "Share" link which shows this behavior.
  This should have the same code as the code snippet below, and use whichever settings are relevant to your report.

  As a last resort, you can link to a repo, but these will be slower for us to investigate.
-->

This can't be completely reproduced in the Playground because it requires two separate projects. One to produce a .d.ts and another to attempt (and fail) to use it.

### 💻 Code

<!-- Please post the relevant code sample here as well. This code and the Playground code should be the same, do not use separate examples -->

Complete and minimal code sample here: https://github.com/kring/ts2611-in-decl-files
You can reproduce it by cloning that repo and running `npm install && npm run build`.

To recreate it manually, define two projects, `a` and `b`, and use project references to link them up. Project `a` exports a class which is created by deriving from a class returned by a function, like this:

```ts
function functionReturningClass() {
  return class ClassInsideFunction {
    get r() {
      return 7;
    }
  };
}

class Something extends functionReturningClass() {
  override get r() {
    return 8;
  }
}

export default Something;
```

(The above is in https://github.com/kring/ts2611-in-decl-files/blob/main/a/something.ts)

Now if we add another module that uses this _to the same project_, then it works great:

```ts
import Something from "./something.js";

const d = new Something();
console.log(d.r);
```

(the above is in https://github.com/kring/ts2611-in-decl-files/blob/main/a/use-from-a.ts)

However, if we add identical code to another project that references this one, like this, then it no longer works anymore:

```ts
import Something from "../a/something.js";

const d = new Something();
console.log(d.r);
```

(the above is from https://github.com/kring/ts2611-in-decl-files/blob/main/b/use-from-b.ts)

### 🙁 Actual behavior

<!-- What happened, and why it was wrong -->

TypeScript reports the following:

```
out/a/something.d.ts:7:9 - error TS2611: 'r' is defined as a property in class '{ readonly r: number; }', but is overridden here in 'Something' as an accessor.

7     get r(): number;
          ~
```

This happens because the generated .d.ts does in fact mix properties and accessors:

```ts
declare const Something_base: {
    new (): {
        readonly r: number;
    };
};
declare class Something extends Something_base {
    get r(): number;
}
export default Something;
```

As far as I can tell, this makes the generated `.d.ts` file unusable.

### 🙂 Expected behavior

<!-- What you expected to happen instead, and why -->

I expected no compiler error, probably because the TS compiler emitted an accessor in `Something_base` rather than a property. Or maybe because it didn't get hung on the mismatch in this scenario?

This was also previously observed here:
https://github.com/microsoft/TypeScript/issues/41347#issuecomment-919256478

Thank you for taking a look!