I have a problem with the following code when trying to create a proxy to a function with many overloads:
// The function to proxy
function original (a: number): boolean;
function original (a: string): boolean;
function original (a: boolean): boolean;
function original (a: number | string | boolean): boolean {
return true;
}
// The proxy
function pass (a: string | number){
return original(a); // here
};
pass(5);
pass('a');
pass(true);
When trying to create a proxy to the original
function TS throw me the following error :
No overload matches this call.
Overload 1 of 3, '(a: number): boolean', gave the following error.
Argument of type 'string | number' is not assignable to parameter of type 'number'.
Type 'string' is not assignable to type 'number'.
Overload 2 of 3, '(a: string): boolean', gave the following error.
Argument of type 'string | number' is not assignable to parameter of type 'string'.
Type 'number' is not assignable to type 'string'.
Overload 3 of 3, '(a: boolean): boolean', gave the following error.
Argument of type 'string | number' is not assignable to parameter of type 'boolean'.
Type 'string' is not assignable to type 'boolean'.(2769)
input.tsx(5, 10): The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible.
Few things to know about this :
- I reduced my bug to this minimal situation where the problem happens
- The
pass(true)
call return an error, so typing seems to work for thepass
function - In my situation, the
original
function is from a module, so if any situation exist without modifications on it would be perfect
Here is a TS Playground with the previous code.
CodePudding user response:
If getting rid of the error is your objective, then checking the type before calling the original function will get rid of the error.
function pass (a: string | number){
if (typeof a === "number") {
return original(a);
} else if(typeof a === "string"){
return original(a);
}
throw new Error(`Expected string or number`);
};
CodePudding user response:
Just cast it to needed type
function original(a: number): boolean;
function original(a: string): boolean;
function original(a: boolean): boolean;
function original(a: number | string | boolean): boolean {
return true;
}
const pass = original as (a: string | number) => boolean
pass(5);
pass('a');
pass(true);