S
S
Spooky 20202021-11-20 02:59:30
typescript
Spooky 2020, 2021-11-20 02:59:30

What's wrong with function overload signature?

Linter is unhappy and issues this:

This overload signature is not compatible with its implementation signature .ts(2394)
The implementation signature is declared here.

TypeScript version 4.4.3

Implementation itself:
function getProductCollection(func: (error: Error,        data: null,                  info: string) => any): void;
function getProductCollection(func: (error: null,         data: ProductUnit[],         info: string) => any): void;
function getProductCollection(func: (error: null | Error, data: ProductUnit[] | null,  info: string) => any): void { }

What is the problem? What did I miss?
Or, in this situation, are the two callback variants considered to be the same parameter, even though its own arguments are different?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Dmitry Belyaev, 2021-11-20
@spooky_2020

The overload implementation must contain in each argument a union from all possible combinations, that is, in your case like this:

function getProductCollection(func:
    | ((error: Error, data: null, info: string) => any)
    | ((error: null, data: ProductUnit[], info: string) => any)
): void {}

The point is that the type
((error: Error, data: null, info: string) => any) | ((error: null, data: ProductUnit[], info: string) => any)
It's not at all the same as
(error: null | Error, data: ProductUnit[] | null,  info: string) => any
Well, by the way, overload in this case is not particularly needed, and even harmful .
Also, this type has 2 problems:
1. The func callback cannot be called normally, since without casting all arguments are generalized to the never type
2. The code calling getProductCollection will not be able to get the normal types for the callback, it will need to explicitly specify the types 1 of the options, which again makes this type extremely useless.
You can overload the callback itself:
function getProductCollection(func: {
    (error: Error, data: null, info: string): any;
    (error: null, data: ProductUnit[], info: string): any;
}): void {}
This will protect the internals of getProductCollection from being called incorrectly, but on the outside, you will get a generic type in the callback:
(error: null | Error, data: ProductUnit[] | null,  info: string) => any
This will force the calling code to either do unnecessary checks or cast types, so if you don't need strong guarantees within a single function, then you can get away with a simple option:
function getProductCollection(func: (error: null | Error, data: ProductUnit[] | null,  info: string) => any): void { }

Of course you can freeze

Но работать это будет весьма ограничено:
https://www.typescriptlang.org/play?#code/C4TwDgpg...

PS don't ever use the any type , in your case it's better to use the void type as the return type for the callback if you don't use it in any way.
Also , take a look at node typing:
https://github.com/DefinitelyTyped/DefinitelyTyped...
https://github.com/DefinitelyTyped/DefinitelyTyped...
Maybe you should not complicate the use of your function with type variance for data?
And why not use promises instead of callbacks at all?

W
WbICHA, 2021-11-20
@WblCHA

What did I miss?

You missed the fact that you have a special case of a function from the implementation in the overload, but it should be the other way around.
Now if you pass this callback, for example:
(error: Error,        data: null,                  info: string) => any

Then in the function itself, nothing prevents us from calling kb with nullinstead of Error.
This is how it will work:
function getProductCollection(func: (error: null | Error, data: ProductUnit[] | null, info: string) => any): void;
function getProductCollection(func: (error: Error, data: null, info: string) => any): void { }

But that's not it.
In any case, the most important question that I asked in the comments, what is the overload for? Here you need a union. And the question is how much it is really needed.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question