提问人:manidos 提问时间:5/19/2021 最后编辑:Gajanan Kulkarnimanidos 更新时间:5/19/2021 访问量:547
如何根据事件名称缩小回调事件类型范围
How to narrow callback event type based on event name
问:
我正在尝试实现一个事件发射器。代码非常简单。
现在认为事件类型是 。
这就是问题所在,我想将类型缩小到正确的类型(取决于传递给函数)。tsc
eventHandler
'ErrorEvent' | 'MessageEvent'
tsc
eventName
on
能做到吗?
定义
interface Event {
code: string;
}
interface ErrorEvent extends Event {
xxx: number;
}
interface MessageEvent extends Event {
yyy: number;
}
interface Events {
error: ErrorEvent,
message: MessageEvent
}
type EventHandler = (event: Events[keyof Events]) => void;
TS 代码
function on (eventName: keyof Events, eventHandler: EventHandler) {
console.log(eventName)
}
on('message', (event) => { // ErrorEvent | MessageEvent
console.log(event)
console.log(event.code)
console.log(event.xxx) // Property 'xxx' does not exist on type 'ErrorEvent | MessageEvent'.
console.log(event.yyy) // Property 'yyy' does not exist on type 'ErrorEvent | MessageEvent'.
})
答:
4赞
aleksxor
5/19/2021
#1
首先,您必须摆脱 EventHandler 作为联合类型:
type EventHandler<K extends EventKeys> = (event: Events[K]) => void
这样,您就可以为每个混凝土的处理程序获得一个混凝土类型。
然后,确保函数的第二个参数类型依赖于第一个参数类型。因此,您必须在函数中引入一个类型参数才能将类型排在一行:K
on
function on <K extends EventKeys>(eventName: K, eventHandler: EventHandler<K>): void {}
我相信这应该做:
interface Event {
code: string;
}
interface ErrorEvent extends Event {
xxx: number;
}
interface MessageEvent extends Event {
yyy: number;
}
interface Events {
error: ErrorEvent,
message: MessageEvent
}
type EventKeys = keyof Events
type EventHandler<K extends EventKeys> = (event: Events[K]) => void;
function on <K extends EventKeys>(eventName: K, eventHandler: EventHandler<K>): void {
console.log(eventName)
}
on('message', (event) => {
console.log(event)
console.log(event.code)
console.log(event.xxx) // Property 'xxx' does not exist on type 'MessageEvent<any>'.
console.log(event.yyy)
})
评论