Reputation: 2206
I can't understand it. I am knew to TypeScript and I am trying to stick to its recommendations as much as possible but this one makes no sense to me.
Reading the tip, I see the definition of type EffectCallback
which is, among other things:
type EffectCallback = (() => void)
Just to see if it makes any difference, I put the definition of the type directly and as you can see, it doesn't trigger TypeScript anymore.
What am I missing?
And another thing is, according to what TypeScript tells me, useEffect
expects an EffectCallback
, which is at best a function that returns void
as a parameter.
The thing is that according to React documentation about useEffect
, I can pass a function that returns a function. React uses this function for cleanup purposes.
My guts tell me there is one small thing I can't get my finger on that would otherwise allow me to figure this out! 😅
Upvotes: 6
Views: 5393
Reputation: 31585
EffectCallback
is the type of the function you pass to useEffect
.
If you want to get the type of the clean up function of useEffect
you can simply use ReturnType<EffectCallback>
.
e.g.
useEffect((): ReturnType<EffectCallback> => {
return (): void => {}
})
You can also take a look at the type EffectCallback
and see what it is
type EffectCallback = () => (void | Destructor);
declare const UNDEFINED_VOID_ONLY: unique symbol;
type Destructor = () => void | { [UNDEFINED_VOID_ONLY]: never };
Upvotes: 2
Reputation: 84912
In your first code example you have this:
(): EffectCallback => {
That means this is a function that returns an EffectCallback
. However, that's not what useEffect
is expecting. The function needs to be an EffectCallback
, not return one. An EffectCallback
is either a function that returns nothing, or a function that returns a teardown function.
In your second example, you move on to this:
(): (() => void) => {
Now you're saying it's a function that returns a teardown function. And a function which returns a teardown function is one of the legal ways to do an EffectCallback, so it matches.
Unless you're using a lint rule that requires explicit return types, i wouldn't bother doing explicit return types with useEffect
. It's simpler to just do () => {
, and if the code you write returns something that's illegal for useEffect
, typescript will point that out.
Upvotes: 7