Repository navigation
cannot auto parse right type in these code #13844
Description
Activity
I tried to fix this with #6118 but it breaks existing code. I gave the reason in this comment.
Duplicate of #3667, except for statics.
- addedDuplicateAn existing issue was already createdAn existing issue was already created
on Feb 2, 2017 Not Duplicate of #3667
I don't think we are talking about a same thing...
I mean, if without the codeGetEventHandler(event: string) { return D.h[event]; }
type of D.h is already confirmed to right type and D.h[e] is right type
so why add a function returning it will change this fact and let it lose its type?Sorry, I missed the second line of the "actual" description where you talked about removing GetEventHandler.
This is actually the same issue caused by #10978.
The compiler is building a new type
Dand it needs to to figure out ifDcorrectly extendsC, so- compare all members of
DtoC- compare
GetEventHandlerin bothDandC- compare return type of
D.GetEventHandlertoC.GetEventHandler- Return type of
D.GetEventHandleris not defined, infer it from function declaration- so what is the type of
D.h- that is not defined, infer it from initialization
- so what is the type of that
mergeObjectcall?- do overload resolution, and check the arguments
- compare
Hash<EventHandler>to{ b: (s:D)=> void }- so what are the properties of
D? - There is one
D.GetEventHandler, but what is its type? - well, we were just trying to figure this out, since we do not know, call it
any. - and tell the user we just did that, i.e. no implicit any error
- so what are the properties of
- compare
- do overload resolution, and check the arguments
- so what is the type of that
- that is not defined, infer it from initialization
- so what is the type of
- Return type of
- compare return type of
- compare
- compare all members of
- addedDesign LimitationConstraints of the existing architecture prevent this from being fixedConstraints of the existing architecture prevent this from being fixedand removedDuplicateAn existing issue was already createdAn existing issue was already created
on Feb 2, 2017 well let's consider what will happen when we rename D.GetEventHandlers to D.a like
class D extends C { a(event: string) { return D.h[event]; } static h = mergeObject<Hash<EventHandler>>( { b:function(s:D){} },C.h); }now we want to know type of D.a
so what's the type of D.a?
so what is the type of D.h
that is not defined, infer it from initialization
so what is the type of that mergeObject call?
do overload resolution, and check the arguments
compare Hash to { b: (s:D)=> void }
so what are the properties of D?
There is one D.a, but what is its type?it seems like it will meet the same problem, but IT"S NOT
why?
i guess, when we try to compare Hash to { b: (s:D)=> void }
what's type of D? extends BaseEventDealer, is it extends correctly? depends on type of D.GetEventHandler, so we check D.GetEventHandler and boombut, consider this:
what's type of D? extends BaseEventDealer, is it extends correctly? depends on type of D.GetEventHandler, so we check D.GetEventHandler
we don't know, so we call it any
so is it extends correctly when D.GetEventHandler is any?
yes
so compare Hash to { b: (s:D)=> void }
yes
and so on, finally we got type of D.h
and finally we got type of D.GetEventHandlerI mean, here we got an error of recursive type parsing, but after we temporary consider it as any, everything will go just fine.Will it be a solution?
consider the same problem in #10978.
`class M {
constructor(fn: () => any) { }
}const a = new M(() => a); /`
as RyanCavanaugh commented:
Let's figure out the type of a from its initializer
What is the type of new M ?
Resolve M to a constructor function
Which overload, if any, of the function is applicable?
There's one overload, is it applicable?
There's a function here, its argument list OK, is its return type OK?
That depends, is the type of a an OK return type for the overload under consideration?
PANIC, we are trying to see the type of a while resolving a's type!then we don't know type of a, then we temporary treat is as any,
so when its type is any, is its return type OK?
yes
and finally can we get type of the temporary any?
yes
and resolvedI mean, here we got an error of recursive type parsing, but after we temporary consider it as any, everything will go just fine.Will it be a solution?
things can have only one type. having a type
anysome time and some other types a typeCwould lead to surprises and phantom errors.maybe I should not call it any, we can call it unsolved(which treat as any)
then we cached all unsolved symbols and parse it again after all other symbols, if it still unsolved, then make it implicit anyIt does not matter what you call it. What matters is the same expression has different types at different places.
I try to explain it in another way
when we meet a symbol which type is unable to parse but we know what it should be.
then we assume it is what it should be and we try to see if it will lead to any logical conflictsthis is not how the typescript compiler works.
- locked and limited conversation to collaborators
on Jun 19, 2018
TypeScript Version: 2.1.4
Code
Expected behavior:
type of D.h should be Hash<EventHandler>
type of return value of D.GetEventHandler should be EventHandler
Actual behavior:
type of D.h and return value of D.GetEventHandler both is ImplicitAny
but if you remove D.GetEventHandler or change its name, h will get right type
or you manually declare h:Hash<EventHandler> or GetEventHandler(event: string):EventHandler, they will both get right type