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
Contextual narrowing not narrowing on generic map.Β #45234
declareconsteventType: keyofDocumentEventMap;document.addEventListener(eventType,(event)=>{event;// Here `event` is `Event | UIEvent | AnimationEvent | MouseEvent | InputEvent | FocusEvent | CompositionEvent | ... 9 more ... | ClipboardEventif(eventType===`click`){event;// Expected: `event` to be type `MouseEvent`. Actual: It's the union from above.}});
π Actual behavior
Second reference of event is type Event | UIEvent | AnimationEvent | MouseEvent | InputEvent | FocusEvent | CompositionEvent | ... 9 more ... | ClipboardEvent.
π Expected behavior
Second reference of event to be of type MouseEvent.
Generic functions like document.addEventListener() have their type parameters specified when you call them. In the case above, the K type parameter is inferred to be keyof DocumentEventMap and therefore the type of event in the callback is the full union; it is no longer "generic" in the way that #43183 (the contextual narrowing feature) would have any bearing on.
It seems like what you really want is something like #27808 where the type parameter K is treated as some unknown single member of the keyof DocumentEventMap union... although then the compiler might not even let you call document.addEventListener() with a union-typed eventType.
This also feels like eventType and event are supposed to be correlated unions but the compiler has no way to track that; which is #30581. (This is where #25051 would have helped, if you could wrap the call to document.addEventListener() in a hypothetical type switch (eventType) {...} block. Oh well!)
Reacted by Andrii Dieiev, Martin Johns and James Whitney
Activity
jcalz commentedon Jul 29, 2021
Generic functions like
document.addEventListener()have their type parameters specified when you call them. In the case above, theKtype parameter is inferred to bekeyof DocumentEventMapand therefore the type ofeventin the callback is the full union; it is no longer "generic" in the way that #43183 (the contextual narrowing feature) would have any bearing on.It seems like what you really want is something like #27808 where the type parameter
Kis treated as some unknown single member of thekeyof DocumentEventMapunion... although then the compiler might not even let you calldocument.addEventListener()with a union-typedeventType.This also feels like
eventTypeandeventare supposed to be correlated unions but the compiler has no way to track that; which is #30581. (This is where #25051 would have helped, if you could wrap the call todocument.addEventListener()in a hypotheticaltype switch (eventType) {...}block. Oh well!)whitneyit commentedon Jul 29, 2021
Thanks Joe Calzaretta (@jcalz) for the detailed response! I agree that this is similar to #30581.
Unlike #30581, I was under the impression that the
ifcheck would be sufficient to narrow the type toMouseEvent.fatcerberus commentedon Jul 30, 2021
Right - the compiler doesnβt understand that
eventTypeandeventare interrelated for the purposes of type narrowing.typescript-bot commentedon Aug 7, 2021
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.