Adrien
Adrien

Reputation: 2206

Function return type mismatching with TypeScript

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.

See how TypeScript tells about an issue with the return type

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.

enter image description here

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.

TypeScript tells us <code>useEffect</code> expecs an EffectCallback

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

Answers (2)

Vencovsky
Vencovsky

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

Nicholas Tower
Nicholas Tower

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

Related Questions