typescript - OpenTok 事件 Typescript 输入
问题描述
我试图通过OpenTok API使用“信号”事件来发布/订阅来实现聊天。
这是我的事件监听器(接收到信号):
// Listen for signal CHAT_MESSAGE
sess.on('signal:CHAT_MESSAGE', event => {
const message = event.data
...
})
问题是打字稿不能识别event.data
为有效属性。类型来自 Session 类:
Session.signal: Event<'signal', Session> & {
type?: string;
data?: string;
from: Connection;
};
我尝试从 Session 类中选择类型,例如
const message = event.data as Session['signal']
打字稿抱怨Property 'data' does not exist on type 'Event<string, any>'.
我怀疑这是因为 TS 无法正确识别事件类型......
然后我尝试先转换为“未知”:
const signal = (event as unknown) as Session['signal']
const msg = signal.data
现在 TS 抱怨:Property 'data' does not exist on type '(signal: { type?: string | undefined; data?: string | undefined; to?: Connection | undefined; }, callback: (error?: OTError | undefined) => void) => void'.ts(2339)
我不知道为什么它不认为这data
是一个道具,同时它似乎说它是......
如何解决这个问题,最好不禁用 TS 类型检查?
解决方案
问题是Session['signal']
一个函数:
signal(
signal: { type?: string, data?: string, to?: Connection },
callback: (error?: OTError) => void
): void;
您可能需要的类型来自Session
的类祖先OTEventEmitter
:
export class Session extends OTEventEmitter<{
...
signal: Event<'signal', Session> & {
type?: string;
data?: string;
from: Connection;
};
...
OTEventEmitter.on
方法类型:
class OTEventEmitter<EventMap> {
on<EventName extends keyof EventMap>(
eventName: EventName,
callback: (event: EventMap[EventName]) => void,
context?: object
): void;
on(
eventName: string,
callback: (event: Event<string, any>) => void,
context?: object
): void;
...
正如您可能会注意到,当Session
扩展OTEventEmitter
时signal:CHAT_MESSAGE
,EventMap
. 只有signal
.
因此,如果您希望您signal:CHAT_MESSAGE
被视为一个signal
事件,您应该将其写为:
sess.on('signal:CHAT_MESSAGE' as 'signal', event => {
const message = event.data // no error
// `event` has type
// Event<'signal', Session> & {
// type?: string;
// data?: string;
// from: Connection;
// }
...
这种类型转换没有运行时伪影。唯一的目的是确保您的事件与'ssignal:CHAT_MESSAGE
具有相同的结构。signal
尽管现在与as
关键字一样,但您有责任确保这一点成为现实。
推荐阅读
- c++ - 找不到 -lopencv_contrib 找不到 -lopencv_legacy
- python - 如何使python对象json序列化?
- ocaml - 相同的 let 绑定导致不同的编译结果
- kubernetes - 用于从 Azure DevOps 中删除多个离线代理的 API
- scroll - FLUTTER 如何正确实现 TrackingScrollController?
- user-interface - 如何更改 GTKWidget 的厚度?
- websphere-liberty - consoleSource 和 consoleLogLevel 与 server.xml 中的日志设置有什么关系?
- javascript - Cypress - 为所有 XHR 请求添加自定义标头
- javascript - 使用 socket.io-client 处理数据
- javascript - Javascript排序数组并通过网络同步