我试图使用带有EventSource的类型记录,但在使用命名事件时不能正确键入响应。
我试过了
const evtSource = new EventSource('/my-url');
const parseMyEvent = (evt: Event) => {
const data: MyDataInterface = JSON.parse(evt.data);
console.log(data)
}
evtSource.addEventListener('my-event', parseMyEvent);失败,因为Event没有属性data。
const evtSource = new EventSource('/my-url');
const parseMyEvent = (evt: MessageEvent) => {
const data: MyDataInterface = JSON.parse(evt.data);
console.log(data)
}
evtSource.addEventListener('my-event', parseMyEvent);在evtSource.addEventListener('my-event', parseMyEvent)上失败,“没有重载匹配此调用。”
我知道MessageEvent是一个通用接口,但是我应该使用什么作为它的类型呢?
我使用的是TS 3.5.3,所以我尝试安装外部类型的@types/eventsource,但也没有成功(我知道,它是用于polyfill EventSource库的,但我尝试了)
当使用泛型evtSource.onMessage = fn时,它的工作没有任何问题。
应该可以在TS中键入EventSource事件的侦听器/响应,但如何键入呢?
发布于 2021-07-30 18:02:30
下面的代码应该可以工作。基本上,您使用的是类型记录的类型断言,让编译器相信底层事件实际上是MessageEvent类型的对象
const evtSource = new EventSource('/my-url');
const parseMyEvent = (evt: Event) => {
const messageEvent = (evt as MessageEvent); // <== This line is Important!!
const data: MyDataInterface = JSON.parse(messageEvent.data);
console.log(data)
}
evtSource.addEventListener('my-event', parseMyEvent);发布于 2021-11-28 02:17:48
addEventListener方法在EventSource上有一个泛型,它引用类型映射接口(EventSourceEventMap)。正如评论中提到的。泛型最初只接受"error" | "message" | "open",但这是因为默认情况下,这些类型是映射中定义的唯一类型。这样做的目的是为您所添加的任何自定义事件添加您自己的类型的映射。
在你的情况下,你需要的是:
declare global {
interface EventSourceEventMap {
['my-event']: MessageEvent<MyDataInterface>;
}
}这样,类型记录不仅知道传递给my-event的消息有一个data属性,而且还知道该属性的类型。
https://stackoverflow.com/questions/66465969
复制相似问题