Typescript args 类型推断的困难

Difficulties with Typescript args type inference

我无法理解推理错误。 useCallback 的 ts linter 下划线 (event: E) 带有下面的消息。 当我用 as T 投射 useCallback 的回调时,linter 消息消失了。有什么办法可以避免这样做吗?我有什么不明白的?

完整代码:

import { DependencyList, useCallback } from 'react'

const useStopBubblingCallback = <T extends (event: E) => any, E extends Event = Event>(
  callback: T,
  deps: DependencyList
) : T =>
  useCallback<T>((event: E) => {
    event.stopPropagation()
    event.preventDefault()
    return callback(event)
  }, deps)

export default useStopBubblingCallback

短消息:

Argument of type '(event: E) => any' is not assignable to parameter of type 'T'.
  '(event: E) => any' is assignable to the constraint of type 'T', 
but 'T' could be instantiated with a different subtype of constraint 
'(event: E) => any'.ts(2345)

您可以将useStopBubblingCallback更改为以下签名(example):

const useStopBubblingCallback = <E extends Event = Event>(
  callback: (event: E) => any,
  deps: DependencyList
) : (event: E) => any =>
  useCallback((event: E) => { /*your code*/ }, deps)

const cb = useStopBubblingCallback((event: MouseEvent) => {}, []) 
// cb: (event: MouseEvent) => any

请注意,在您的情况下,类型参数 E 在外部函数中没有推理候选,因此 TypeScript 无法对 E 做任何有用的事情(它将被固定为 Event一直)。

我们还在 useCallback<T> 中删除了手动类型参数,让编译器自动推断其类型。