-
Notifications
You must be signed in to change notification settings - Fork 270
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(framework): add strict event type checking (#10235)
- Loading branch information
Showing
102 changed files
with
1,006 additions
and
1,243 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,13 @@ | ||
import customElement from "./decorators/customElement.js"; | ||
import event from "./decorators/event.js"; | ||
import eventStrict from "./decorators/event-strict.js"; | ||
import property from "./decorators/property.js"; | ||
import slot from "./decorators/slot.js"; | ||
|
||
export { | ||
customElement, | ||
event, | ||
eventStrict, | ||
property, | ||
slot, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import type UI5Element from "../UI5Element.js"; | ||
|
||
type EventDetailKeys<T extends typeof UI5Element> = keyof InstanceType<T>["eventDetails"]; | ||
type ExtractEventKeys<T extends typeof UI5Element> = EventDetailKeys<T> extends never ? "event name not found in `eventDetails` field" : EventDetailKeys<T>; | ||
|
||
/** | ||
* Returns an event class decorator. | ||
* | ||
* @param { string } name the event name | ||
* @param { EventData } data the event data | ||
* @returns { ClassDecorator } | ||
*/ | ||
const event = <T extends typeof UI5Element, N extends ExtractEventKeys<T>>(name: N, data: { bubbles?: boolean, cancelable?: boolean } = {}): (target: T) => T | void => { | ||
return (target: T) => { | ||
if (!Object.prototype.hasOwnProperty.call(target, "metadata")) { | ||
target.metadata = {}; | ||
} | ||
|
||
const metadata = target.metadata; | ||
if (!metadata.events) { | ||
metadata.events = {}; | ||
} | ||
|
||
const eventsMetadata = metadata.events; | ||
if (!eventsMetadata[name as string]) { | ||
data.bubbles = !!data.bubbles; | ||
data.cancelable = !!data.cancelable; | ||
eventsMetadata[name as string] = data; | ||
} | ||
}; | ||
}; | ||
|
||
export default event; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import UI5Element from "../../src/UI5Element"; | ||
import event from "../../src/decorators/event-strict"; | ||
|
||
// @ts-expect-error eventDetails is fully missing | ||
@event("toggle") | ||
class ComponentWithoutEventDetails extends UI5Element { | ||
myHandler() { | ||
// @ts-expect-error event details is fully missing | ||
this.fireDecoratorEvent("toggle"); | ||
} | ||
} | ||
|
||
// correct event | ||
@event("toggle") | ||
@event("change") | ||
// @ts-expect-error wrong event name | ||
@event("not-found") | ||
class ComponentWithEventDetails extends UI5Element { | ||
eventDetails!: { | ||
toggle: void | ||
change: { | ||
data: string | ||
} | ||
}; | ||
|
||
myHandler() { | ||
// correct event | ||
this.fireDecoratorEvent("toggle"); | ||
|
||
// @ts-expect-error wrong event name | ||
this.fireDecoratorEvent("not-found"); | ||
|
||
// @ts-expect-error wrong data type | ||
this.fireDecoratorEvent("change", { wrongData: "data" }); | ||
// @ts-expect-error wrong data | ||
this.fireDecoratorEvent("toggle", {data: "data"}); | ||
|
||
// still no error if data is missing, will be implemented later | ||
this.fireDecoratorEvent("change"); | ||
|
||
// correct data no error | ||
this.fireDecoratorEvent("change", { data: "data" }); | ||
|
||
} | ||
} | ||
|
||
class BaseComponent extends UI5Element { | ||
// no event details | ||
} | ||
|
||
@event("open") | ||
// @ts-expect-error | ||
@event("not-found") | ||
class ChildComponent extends BaseComponent { | ||
// Base component should provide an empty object, not ANY | ||
eventDetails!: BaseComponent["eventDetails"] & { | ||
open: void | ||
} | ||
handler() { | ||
this.fireDecoratorEvent("open"); | ||
// @ts-expect-error | ||
this.fireDecoratorEvent("not-found"); | ||
} | ||
} |
Oops, something went wrong.