Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Contextual narrowing not narrowing on generic map. #45234

Closed
whitneyit opened this issue Jul 29, 2021 · 4 comments
Closed

Contextual narrowing not narrowing on generic map. #45234

whitneyit opened this issue Jul 29, 2021 · 4 comments
Labels
Duplicate An existing issue was already created

Comments

@whitneyit
Copy link
Contributor

Bug Report

πŸ”Ž Search Terms

πŸ•— Version & Regression Information

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

declare const eventType: keyof DocumentEventMap;

document.addEventListener(eventType, (event) => {
  event; // Here `event` is `Event | UIEvent | AnimationEvent | MouseEvent | InputEvent | FocusEvent | CompositionEvent | ... 9 more ... | ClipboardEvent
  if (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.

@jcalz
Copy link
Contributor

jcalz commented Jul 29, 2021

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!)

@whitneyit
Copy link
Contributor Author

Thanks @jcalz for the detailed response! I agree that this is similar to #30581.

Unlike #30581, I was under the impression that the if check would be sufficient to narrow the type to MouseEvent.

@fatcerberus
Copy link

Right - the compiler doesn’t understand that eventType and event are interrelated for the purposes of type narrowing.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Aug 5, 2021
@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

5 participants