Home > database >  Create a proxy to a function with many overloads in TypeScript
Create a proxy to a function with many overloads in TypeScript

Time:10-19

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 the pass 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);

https://www.typescriptlang.org/play?ssl=15&ssc=1&pln=1&pc=1#code/GYVwdgxgLglg9mABHATjA5jMBDANgCmwC5EwQBbAIwFMUBKEyuOXa7MAbgFgAoUSWAmRpMOAsUQBnKGjDoGiJizade-aPCSoMWPIUbNW7BUqOqea8BqHbReiWSq1EAHykys6V4sMqTv9kQAb15ERBRqKBAUJBkQam4eAF9eXggEaUQAB2xJSUQAXmEdMURcxH13WS83Rxp6QoA H2V2VJ4cvPwAVjpEzsl8AHJsIb7eAfw46nGLHiA

  • Related