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

feat: add strict event type checking #10235

Merged
merged 19 commits into from
Dec 3, 2024
Merged

feat: add strict event type checking #10235

merged 19 commits into from
Dec 3, 2024

Conversation

pskelin
Copy link
Contributor

@pskelin pskelin commented Nov 21, 2024

eventDetails field

This change is introducing a new field in the components

class MyComponent extends UI5Element {
  eventDetails!: {
    "selection-change": SelectionChangeDetails
    "delete": void
  }
}

This field doesn't have runtime semantics, it is only used to provide type information about the events that the component is firing and the corresponding types of the detail parameter.

This enables two new usages

  1. stricter type checking for event decorators and firing events
  2. future support for TSX event handler type generation

strict @event decorator

There is a new event decorator that does strict checks against this field. The old event decorator is deprecated and will be removed. To switch, simple change the import

- import event from "@ui5/webcomponents-base/dist/decorators/event.js";
+ import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";

It is no longer necessary to priovide the event type in the decorator, as TypeScript is able to infer it from the event name and the eventDetails field.

- @event<SelectionChangeDetails>("selection-change", ...)
+ @event("selection-change", ...)

strict fireDecoratorEvent

The method fireDecoratorEvent is now also checking against the eventDetails field ensuring that the event name that is fired is described and that the detail parameter is of the same type as the one in eventDetails. The event type is also inferred from the event name and no longer necessary to pass from outside.

- this.fireDecoratorEvent<SelectionChangeDetails>("selection-change", {...})
+ this.fireDecoratorEvent("selection-change", {...})

extending the eventDetails with more events

If your component extends another component and you try to add new events, you will get a TypeScript error that the new events cannot be assigned to the same field in the base class

class TimeSelectionClocks extends TimePickerInternals {
  eventDetails!: { // ts-error
    "close-picker": void,
  };

// Property 'eventDetails' in type 'TimeSelectionClocks' is not assignable to the same property in base type 'TimePickerInternals'.

In order to correctly extend the base class events, you need to add them as a type as well like this TimePickerInternals["eventDetails"]

class TimeSelectionClocks extends TimePickerInternals {
  eventDetails!: TimePickerInternals["eventDetails"] & {
    "close-picker": void,
  };

@pskelin pskelin marked this pull request as ready for review November 28, 2024 08:26
@pskelin pskelin merged commit 4ff8ab7 into main Dec 3, 2024
10 checks passed
@pskelin pskelin deleted the strict-events branch December 3, 2024 20:02
@ui5-webcomponents-bot
Copy link
Collaborator

🎉 This PR is included in version v2.5.0-rc.3 🎉

The release is available on v2.5.0-rc.3

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants