microsoft / microsoft/TypeScript

A function that returns a class with a property getter is unusable via a declaration file (TS2611)

未关闭
#54,879 6 条评论 4 个 reaction 已指派 1 人 在 GitHub 查看

@weswigham 已经在做这个了。

开始于 2023年7月7日。

Needs Investigation Rescheduled
主要语言
Go
星标
111k
派生
14.4k
平均合并
1 天 19 小时
30 天内合并 PR
117

描述

Bug Report

🔎 Search Terms

TS2611, declaration file, property getter

🕗 Version & Regression Information
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about TS2611, declaration files, property getters
⏯ Playground Link

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

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:

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:

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:

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

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:

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

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!

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。