Repository navigation
Compiler is unable to resolve return type of function even though it is returning function with known return type #26623
Description
Activity
- changed the title
[-]Returning a function with a known return type[/-][+] Compiler is unable to resolve return type of function even though it is returning function with known return type[/+]on Aug 23, 2018 - addedDesign LimitationConstraints of the existing architecture prevent this from being fixedConstraints of the existing architecture prevent this from being fixed
on Aug 23, 2018 RyanCavanaugh commented
on Aug 23, 2018 MemberMore actionsThis is a circular operation, because we have to check what the type of
Person#isNameSameAsNicknameis in order to check the call tocompareNamesto figure out what the return type could be. You can see this because removingisNameSameAsNicknamefromIdentifiablecauses the error to go away.Ryan Cavanaugh (@RyanCavanaugh),
Thanks for your reply. So it sounds like you are saying, the compiler is undergoing the following "thought" process:
- Okay, so
isSameAsNicknamedepends oncompareNames. - And
compareNamesrequires anIdentifiableas input. - And an
Identifiablemust have a property,isNameSameAsNickname, that returns a boolean. - Therefore,
compareNamesdepends onisNameSameAsNickname. - Damn, this is complicated, I give up.
Meanwhile, the human being (me) is undergoing a different thought process:
- Okay, so
isNameSameAsNicknamedepends oncompareNames. - And
compareNamesreturns a boolean. - Therefore
isNameSameAsNicknamemust return a boolean. - Therefore
Personis a legitimateIdentifiable. - Therefore
compareNamescan be called.
This suggests that the order that type checks are performed has a significant effect on whether dependencies resolve or are deemed circular. On the surface, this seems like it shouldn't be hard to fix, but I gather it's a difficult problem or it would already be solved.
This does bring up a question...
The workaround I provided is obviously very simple to implement, so I'm OK using that, but is there a better, more "best practices" way to accomplish this type of thing that avoids this issue altogether?
Reacted by Changdae Park- Okay, so
RyanCavanaugh commented
on Aug 24, 2018 MemberMore actionsI gather it's a difficult problem or it would already be solved.
Yep 😉. 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.
Reacted by Damien Golding, Joel Nordström and Wessel Kronemeijer
TypeScript Version: 3.0.1
Search Terms:
Code
Expected behavior:
Compiles without error
Actual behavior:
The following error occurs:
Comment: This error appears to be incorrect (or at least worded ambiguously) because
isNameSameAsNicknameis not referenced directly or indirectly in one of its return expressions. Specifically,isNameSameAsNicknamedoes not appear directly in the return expressioncompareNames(this)nor does it appear indirectly inidentifiable.name === identifiable.nickname.Workaround:
Declare the return type explicitly:
Playground Link:
This error is indicated in the playground with a red squiggle below
isNameSameAsNickname().Note: Error only occurs if
noImplicitAnyoption is checkedRelated Issues:
asoperator does not work on recursive functions #5403