I am having trouble understanding an inference error. The ts linter underline (event: E)
of useCallback
with the message bellow.
When I cast the callback of useCallback
with as T
the linter message is gone. Is there any way to avoid doing this? What did I didn't understand?
Complete code:
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
Linter message:
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)
You can change useStopBubblingCallback
to the following signature (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
Note, that in your case type parameter E
had no inference candidate in the outer function, so TypeScript cannot do anything useful with E
(it would be fixed to Event
all the time).
We also drop the manual type argument in useCallback<T>
to let the compiler automatically infer its type.