【问题标题】:Argument of type '(e: MediaQueryListEvent) => void' is not assignable to parameter of type '(e: Event) => void''(e: MediaQueryListEvent) => void' 类型的参数不可分配给'(e: Event) => void' 类型的参数
【发布时间】:2021-11-11 15:17:24
【问题描述】:

我创建了以下钩子来监听事件:

const useEventListener = (event: keyof WindowEventMap, callback: (e: Event) => void, element: EventTarget | null = window) => {

  const callbackRef = useRef<(e: Event) => void>(callback)

  useEffect(() => {
    callbackRef.current = callback
  }, [callback])

  useEffect(() => {
    const handler: EventListener = e => callbackRef.current(e);
    element?.addEventListener(event, handler)
    return () => element?.removeEventListener(event, handler)
  }, [event, element])
}

现在我正在尝试创建一个监听媒体查询的钩子。但是,当我将以下函数传递给callback: (e: Event) =&gt; void 时,(e: MediaQueryListEvent) =&gt; setIsMatching(e.matches) 我从打字稿中得到一个错误。自从MediaQueryListEvent extends Event 以来,我一直在苦苦挣扎!我该如何解决?

const useMediaQuery = (mediaQuery: string) => {
  const [isMatching, setIsMatching] = useState(false);
  const [mediaQueryList, setMediaQueryList] = useState<MediaQueryList|null>(null);

  useEffect(() => {
    const list: MediaQueryList = window.matchMedia(mediaQuery)
    setMediaQueryList(list)
    setIsMatching(list.matches)
  }, [mediaQuery])

  # ERROR HERE
  useEventListener("change", (e: MediaQueryListEvent) => setIsMatching(e.matches), mediaQueryList)

  return isMatching;

}

完全错误:

Argument of type '(e: MediaQueryListEvent) => void' is not assignable to parameter of type '(e: Event) => void'.
Types of parameters 'e' and 'e' are incompatible.
    Type 'Event' is missing the following properties from type 'MediaQueryListEvent': matches, media

【问题讨论】:

    标签: reactjs typescript react-hooks react-typescript


    【解决方案1】:

    错误与您正在努力解决的问题(“MediaQueryEvents 扩展事件”)完全合情合理。 Event 缺少一些 MediaQueryListEvents 具有的属性(matchesmedia),因此 Typescript 会抱怨它。

    如果您只使用带有MediaQueryListEvents 的钩子,您可以在钩子callback 参数中将类型从e: Event 更改为e: MediaQueryListEvents(可能需要从您正在使用的任何包中导入该类型定义)。如果您将使用各种不同的事件,则需要将其更改为e: any,或者使用管道运算符为ee: Event | MediaQueryListEvents 等)设置多种可能的类型。

    【讨论】:

    • 我认为唯一的解决方案是给出any 类型。为类型设置 or 选项是不够的,因为那时回调仍应评估/将事件转换为 MediaQueryListEvent。我想确认没有任何更好的解决方案没有出现在我的脑海中
    猜你喜欢
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 2021-04-18
    • 1970-01-01
    • 2022-07-20
    • 2020-04-26
    • 2018-08-27
    • 2023-04-05
    相关资源
    最近更新 更多