You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写具备类型推断能力的通用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 11:34:53