【问题标题】:Compiler says that generic class method references itself directly or indirectly, but it's not编译器说泛型类方法直接或间接引用自己,但事实并非如此
【发布时间】:2020-01-22 17:26:16
【问题描述】:

当我有以下代码(playground link):

class Cls<T = any> {

    method() {
        return this.is(new Cls);
    }

    is(suspect: Cls) { }

}

为什么会出现以下错误?

'method' 隐式具有返回类型'any',因为它没有返回类型注释,并且在其返回表达式之一中直接或间接引用。

[编辑] 我知道我可以添加返回类型注释,但是当它应该自动推断为void时为什么我需要这样做。

【问题讨论】:

  • new Cls 之后添加括号,例如 new Cls()

标签: typescript generics self-reference


【解决方案1】:

你必须明确定义方法method()的返回类型。变成这样:method(): any

【讨论】:

  • 我知道我可以明确返回类型,但为什么必须这样做?应该可以简单推论为void
  • 如果返回类型为void,为什么要使用'return'语句?使用 method() { this.is(new Cls()); 就足够了}
【解决方案2】:

看起来您已经知道如何避免错误(例如,在某处添加类型注释),但您想知道为什么会发生错误。为此,我们可以查看一个非常相似的报告问题,microsoft/TypeScript#26623, a.k.a. "Compiler is unable to resolve return type of function even though it is returning function with known return type"

这基本上是 TypeScript 的设计限制;编译器认为它需要知道new Cls() 结果的完整类型,然后才能确定this.is(new Cls()) 将返回什么(尽管我们 可以很容易地看出这是void 无论如何),并且由于new Cls() 的完整类型取决于method() 的返回类型,因此编译器放弃了。这还不是完整的故事,因为类经常间接地引用自己,而推理通常是有效的。但是关于默认类型参数T = any 的某些东西正在以一种出乎意料的方式使用。您可能会考虑在 GitHub 中打开您自己的问题以获取更多详细信息或进行修复,但我强烈怀疑这将被视为设计限制,甚至是之前链接问题的重复。

根据a comment by the TypeScript development lead

这里真正的问题是,检查器执行的两个主要操作——推理和错误检测——是“同时”发生的。您可以想象一个不同的世界,所有推理都发生,然后所有错误检查都发生,这将避免这个问题,因为检查参数类型是否可分配给参数类型只是错误检查阶段的一部分。但这可能至少是当前实现速度的两倍。

没有可以避免所有循环问题的固定做法。我想说,返回类型注释是这个例子的最佳选择。

好的,希望对您有所帮助;祝你好运!

【讨论】:

  • 不,我只是一个 TypeScript 爱好者!
猜你喜欢
  • 1970-01-01
  • 2014-06-04
  • 1970-01-01
  • 1970-01-01
  • 2018-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多