如何编写具备类型推断能力的通用React事件监听器Hook?
通用React Hook的TypeScript类型推断问题
我尝试编写一个通用React Hook,可适配符合特定接口的任意事件发射器,代码如下:
import { useEffect } from 'react' type EventsMap = Record<string, (...args: any) => void> type EventName<EM extends EventsMap> = keyof EM type EventListener<EM extends EventsMap, EN extends EventName<EM>> = EM[EN] export type EventEmitter<EM extends EventsMap> = { on<K extends keyof EM>(event: K, cb: EM[K]): () => void } export function useEventListener< EM extends EventsMap, EN extends EventName<EM>, >( emitter: EventEmitter<EM> | undefined | null, eventName: EN, listener: EventListener<EM, EN>, ) { useEffect(() => { return emitter?.on(eventName, listener) }) }
上述代码可正常运行,但仅在调用时手动指定类型的情况下,类型校验才正确:
useEventListener<MyEventMap, keyof MyEventMap>(emitter, 'myEvent', () => { console.log('hi there') })
我困惑的是,TypeScript明明能识别emitter是EventEmitter实例,却无法从中推断EventMap以约束事件名称。我感觉这和TypeScript中「类型参数依赖导致推断失败」的问题相关,但无法准确表述关联点。
补充说明
在TypeScript Playground的示例中,最后几行可看到问题表现:调用useEventListener时EventMap被推断为默认类型,导致监听器接收的事件参数类型为any。
内容的提问来源于stack exchange,提问作者Fuad Saud
相关产品推荐
相关产品推荐

