You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Unable to resolve a const variable type with nested ref with noImplicitAny enabled #17386
Expected behavior:
Since thing is being defined directly, the compiler should still intuit that it's of type Thing when noImplicitAny is enabled.
Actual behavior:
The compiler doesn't like the nested data reference via the loop and lastThing reference and says thing will be "any" and I have to explicitly define thing as type Thing:
'thing' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
This is a simplified version of the actual code; the existence of a loop and the reference to the prior instance are critical to the actual usage. Repros with the TS playground with noImplicitAny enabled.
The problem is not Thing declaration location, it is that type of thing depends on type of lastThing, whose type inside the loop depends on the type of thing. giving thing an explicit type would resolve the circular dependency and avoid the any type.
Thanks for your response. I didn't understand the logic behind what you wrote, unfortunately.
Shouldn't lastThing's type be sufficiently validated to be either Thing or null, with the explicit declaration of lastThing's type as in my second post? Is the explicit declaration not trusted?
I also don't understand why the type of thing depends on the type of lastThing. Can you clarify that? It would seem to me that the invocation of a constructor of a type should restrict the resulting value to be that type. Is that not trusted?
The compiler tries to do control flow analysis to know the types of variables at a given locaiton. this is what allows things like var x: string | null; if(x) x.length; since the compiler knows that insider the if statement x can nto be null.
similarly in a loop, the compiler tries to figure out what the type of lastThing is. remember a loop body has two possible entry points, either from the top on first iteration, or from the end of previous iterations; so because of the assignment it is the type of thing, but to know the type of thing, it needs to resolve a call to new Thing and to do that it needs to know what is lastThing, but it was trying to figure out that in the first place.
The compiler uses any to break such ties, and flags that when --noImplictAny is set.
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.
Activity
takamori commentedon Jul 25, 2017
I should have noted that we also have strictNullChecks enabled as well; defining the type of lastThing doesn't help.
mhegazy commentedon Aug 24, 2017
The problem is not
Thingdeclaration location, it is that type ofthingdepends on type oflastThing, whose type inside the loop depends on the type ofthing. givingthingan explicit type would resolve the circular dependency and avoid theanytype.takamori commentedon Aug 24, 2017
Thanks for your response. I didn't understand the logic behind what you wrote, unfortunately.
Shouldn't lastThing's type be sufficiently validated to be either Thing or null, with the explicit declaration of lastThing's type as in my second post? Is the explicit declaration not trusted?
I also don't understand why the type of thing depends on the type of lastThing. Can you clarify that? It would seem to me that the invocation of a constructor of a type should restrict the resulting value to be that type. Is that not trusted?
mhegazy commentedon Aug 25, 2017
The compiler tries to do control flow analysis to know the types of variables at a given locaiton. this is what allows things like
var x: string | null; if(x) x.length;since the compiler knows that insider the if statementxcan nto benull.similarly in a loop, the compiler tries to figure out what the type of
lastThingis. remember a loop body has two possible entry points, either from the top on first iteration, or from the end of previous iterations; so because of the assignment it is the type ofthing, but to know the type ofthing, it needs to resolve a call tonew Thingand to do that it needs to know what islastThing, but it was trying to figure out that in the first place.The compiler uses
anyto break such ties, and flags that when --noImplictAny is set.takamori commentedon Aug 25, 2017
Thanks for the clarification, and I see how the "Design Limitation" label applies here now.
mhegazy commentedon Sep 8, 2017
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.