Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork1.7k
Generic events#10193
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
Generic events#10193
Uh oh!
There was an error while loading.Please reload this page.
Conversation
nx-cloudbot commentedFeb 1, 2023 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
☁️ Nx Cloud ReportWe didn't find any information for the current pull request with the commit9a07b1b. Checkthe Nx Cloud Github Integration documentation for more information. Sent with 💌 fromNxCloud. |
ammarahm-ed commentedFeb 15, 2023 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
This is ok but I think it doesn't really solve the problem. All Views "Should" infer to correct types in events automatically without passing some Generic or anything. newButton().on<Button>("loaded",(eventData)=>{eventData.object;// TypeScript infers this to be a Button}); is almost as much work as doing newButton().on("loaded",(eventData)=>{eventData.objectasButton;}); The ideal way would be to not have to pass any generic at all when you are subscribing to an event on Button. For example: newButton().on("loaded",(eventData)=>{eventData.object// is Button automatically}); Also my question, why does this work or to be more specific, how does this work: // Button-specific events don't require passing the generic:newButton().on("tap",(eventData)=>{eventData.object;// TypeScript infers this to be a Button}); |
@ammarahm-ed be careful some views fire event for which the object is not them self! I know some plugins already do that. And I think some N components also do that. Will try to find them |
Uh oh!
There was an error while loading.Please reload this page.
With this PR, EventData and methods for adding/removing listeners will now be generic:
Please do give comment on the discussion points I've posted and (once we've reviewed it and prepared a build of it) a try on your projects, as I fully expect it'll result in some TypeScript grumbles.
PR Checklist
What is the current behavior?
Types for EventData and adding/removing listeners are non-generic, so we always have to write
eventData.object as Button
if we want anything more specific than an Observable.What is the new behavior?
Improved inference in most cases. The events in Application have always beenvery messy though, so I've left those as defaulting to Observable even though some could be narrowed to View, as I simply can't get my head round them.
Note that this PR would introduce breaking changes for library authors. As although we do provide default args for each generic, if they've extended
on
anywhere, they'll have to add the generic, as demonstrated in thisplayground:For discussion
What should the generics be?
The generics implemented in this PR are "better than nothing", but still not ideal. See what I ideally wanted to implement vs. what I was able to get working:
The former is more strictly correct, but I just couldn't get TypeScript to accept it 🤷
Should we narrow the default generic for EventData in the first place?
Although I think itis correct for the methods for adding/removing event listeners to have more narrow generic defaults than just
Observable
, e.g.:... I am unsure about whether the EventData interfaces should behave the same:
Mainly because we don't know whether others might repurpose the same event (SelectedIndexChangedEvent can be used for more than just SegmentedBar, and indeed there are duplicates of this interface across the codebase). Of course consumers can just specify the generic explicitly if they want to override the assumed default of SegmentedBar, so it's not the end of the world whichever choice we go with.