编译器说泛型 class 方法直接或间接引用自身,但事实并非如此

Compiler says that generic class method references itself directly or indirectly, but it's not

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

class Cls<T = any> {

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

    is(suspect: Cls) { }

}

为什么会出现以下错误?

'method' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.

[编辑] 我知道我可以添加 return 类型注释,但是当它应该被自动推断为 void.

时为什么我需要这样做

您必须显式定义方法 method() 的 return 类型。像这样:method(): any

看起来您已经知道如何避免错误(例如,在某处添加类型注释),但您想知道为什么 错误会发生。为此,我们可以查看一个非常相似的报告问题 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()) 将 return 的内容(即使 we 可以很容易看出这是 void 无论如何),并且由于 new Cls() 的完整类型取决于 method() 的 return 类型,编译器放弃了。这不是完整的故事,因为 类 经常间接引用自己,而推理通常是有效的。但是关于默认类型参数 T = any 的一些事情正在以一种意想不到的方式使用。您可能会考虑在 GitHub 中打开您自己的问题以获取更详细的信息或修复,但我强烈怀疑这将被视为设计限制甚至是先前链接问题的副本。

根据a comment by the TypeScript development lead

The real issue here is that the two main operations the checker does - inference and error detection - occur at the "same time". You could imagine a different world where all inference happens, then all error checking happens, which would avoid this problem because the check of whether the argument type is assignable to the parameter type would only be part of the error-checking phase. But this would likely be at least twice as slow as the current implementation.

There's no set practice that will avoid all circularity issues. The return type annotation is the best alternative for this example, I would say.

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