Deciding whether to raise an issue on GitHub is ultimately up to you, but it is likely that the issue would be closed due to being classified as either a design limitation or functioning as intended. You can refer to microsoft/TypeScript#38724 and microsoft/TypeScript#35546 for similar cases, or you can search for the specific term in the issue tracker. Usually, when the compiler warns about circularity, it is because the type inference algorithm would lead to an infinite regress if it continued. This implies that there is indeed a circular reference present. Whether an average person could comprehend this without getting stuck in the same loop is not particularly relevant:
This situation is inherently circular, and the ability to reason our way out of it does not negate that fact. The core checking algorithm lacks the mechanisms needed to resolve this circularity.
In this scenario, I am drawing insights from microsoft/TypeScript#38724 and this particular comment:
This remains a circularity; in order to validate the type assertion from Object.assign(nation, this)
to Nation
, TypeScript must determine the type of this
, which relies on the return type of clone
.
Based on my analysis, here is a potential issue explanation for your case.
This circularity is causing the compiler to encounter issues. While my explanation is speculative, someone with deeper compiler knowledge could review and correct any inaccuracies. The crucial point to note is that even if it seems obvious to us that the return type of thing.method(this)
is void
, the compiler cannot easily process such observations due to hitting a circularity.
What bothers me about this type of response is that it implies that any use of this
within a class without comprehensive annotations should prompt the compiler to flag circularities. The this
type inherently introduces circular references. Yet, in practice, the compiler often overlooks such circular dependencies. Moreover, minor code alterations can magically eliminate the error:
class MyClass<T> {
method(thing: Thing) { // no error now
const ret = thing.method(this);
return ret;
}
}
Presumably, this discrepancy is linked to the precise sequence of operations in the type inference algorithm, tailored to address common scenarios. Therefore, if you can present a compelling argument for your specific use case, you might consider submitting it as a suggestion rather than an issue, potentially avoiding immediate closure. However, it is unlikely that the matter will receive significant attention, especially considering that it can be easily resolved with a type annotation:
class MyClass<T> {
method(thing: Thing): void { // annotate
return thing.method(this);
}
}
Test the code on TypeScript Playground