Last active
April 17, 2023 09:23
-
-
Save ryuujo1573/b9bd37f549988924125e799a5b063288 to your computer and use it in GitHub Desktop.
Demonstrates how to define type of custom `Event`s
This file contains hidden or 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
// aliases | |
type MyEvent = PingEvent | MessageEvent; | |
type EventTypes = MyEvent["type"]; | |
type EventHandler<T> = (payload: T) => void; | |
type EventHandlers = { | |
ping: EventHandler<PingEvent>[]; | |
message: EventHandler<MessageEvent>[]; | |
}; | |
// type defs | |
interface PingEvent extends Event { | |
type: "ping"; | |
foo: number; | |
} | |
interface MessageEvent extends Event { | |
type: "message"; | |
bar: string; | |
} | |
// type guard | |
function isMyEvent(t: Event): t is MyEvent { | |
return ["ping", "message"].includes(t.type); | |
} | |
class _ { | |
// approach 0: (fine) | |
// seperated handers | |
#__pingEventHandlers: EventHandler<PingEvent>[]; | |
#__messageEventHandlers: EventHandler<MessageEvent>[]; | |
// approach 1-3 | |
readonly eventHandlers: EventHandlers = { | |
ping: [], | |
message: [], | |
}; | |
dispatchEvent<T extends MyEvent>(event: T): void { | |
if (isMyEvent(event)) { | |
// approach 1: (low readability) | |
// requires a shim for type inferring | |
for (const cb of this.eventHandlers[event.type]) { | |
cb(event as never); | |
} | |
// approach 2: (not recommended) | |
// occurs implicit any | |
this.eventHandlers[event.type].forEach((cb) => cb(event)); | |
// approach 0/3: (recommended) | |
// narrowing using switch expression | |
switch (event.type) { | |
case "ping": | |
// approach 3: | |
this.eventHandlers.ping.forEach((cb) => cb(event)); | |
// approach 0: | |
for (const callback of this.#__pingEventHandlers) { | |
callback(event); | |
} | |
break; | |
// case ... | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment