OpenTok 事件 Typescript 键入
OpenTok event Typescript typing
我正在尝试通过 OpenTok API 使用 'signal' 事件实现聊天 publish/subscribe。
这是我的有效事件侦听器(收到信号):
// Listen for signal CHAT_MESSAGE
sess.on('signal:CHAT_MESSAGE', event => {
const message = event.data
...
})
问题是 typescript 无法将 event.data
识别为有效的 属性。类型来自Session class:
Session.signal: Event<'signal', Session> & {
type?: string;
data?: string;
from: Connection;
};
我试过从 Session class 中选择类型
const message = event.data as Session['signal']
Typescript 抱怨 Property 'data' does not exist on type 'Event<string, any>'.
我怀疑是因为 TS 没有正确识别事件类型...
然后我首先尝试转换为 'unknown':
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
的 class 祖先 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
时,EventMap
中没有 signal:CHAT_MESSAGE
。只有 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;
// }
...
此类型转换没有运行时人工制品。唯一的目的是确保您的 signal:CHAT_MESSAGE
事件与 signal
的事件具有相同的结构。虽然与往常一样使用 as
关键字,但现在您有责任确保它是真实的。
我正在尝试通过 OpenTok API 使用 'signal' 事件实现聊天 publish/subscribe。
这是我的有效事件侦听器(收到信号):
// Listen for signal CHAT_MESSAGE
sess.on('signal:CHAT_MESSAGE', event => {
const message = event.data
...
})
问题是 typescript 无法将 event.data
识别为有效的 属性。类型来自Session class:
Session.signal: Event<'signal', Session> & {
type?: string;
data?: string;
from: Connection;
};
我试过从 Session class 中选择类型
const message = event.data as Session['signal']
Typescript 抱怨 Property 'data' does not exist on type 'Event<string, any>'.
我怀疑是因为 TS 没有正确识别事件类型...
然后我首先尝试转换为 'unknown':
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
的 class 祖先 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
时,EventMap
中没有 signal:CHAT_MESSAGE
。只有 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;
// }
...
此类型转换没有运行时人工制品。唯一的目的是确保您的 signal:CHAT_MESSAGE
事件与 signal
的事件具有相同的结构。虽然与往常一样使用 as
关键字,但现在您有责任确保它是真实的。