简体   繁体   中英

How to implement an interface with multiple anonymous functions in typescript

I am trying to implement interface shown below in typescript

interface A{
  (message: string, callback: CustomCallBackFunction): void;
  (message: string, meta: any, callback: CustomCallBackFunction): void;
  (message: string, ...meta: any[]): void;
  (message: any): void;
  (infoObject: object): void;
} 

here CustomCallBackFunction defintion

type CustomCallBackFunction= (error?: any, level?: string, message?: string, meta?: any) => void;

I am unable to implement the interface with class. Any idea how to do this.

This is for method overloading For example, i have a class B with a variable of type A with implementation referring to all other options.

class B {
public c: A
}

Then i can call

const b =new B();
b.c(message,callback);
b.c(message,meta,callback);
b.c(message,meta);
b.c(infoObject);

Sadly, the only way to implement this interface to to make all arguments any .

This interface is much like function overloads. Which means the implementation function must take an argument that is a union of all possibilities of the argument at that position.

  1. The first argument is string , string , string , any or object . So the type is string | object | any string | object | any string | object | any , which simplifies to just any since any includes the other possibilities.

  2. The second argument is CustomCallBackFunction | any | undefined CustomCallBackFunction | any | undefined CustomCallBackFunction | any | undefined , which again is any

  3. The third argument could be CustomCallBackFunction or the second item of ...meta: any[] , so again, that one is any .


So, given that all arguments must be of type any , and there may any number of arguments, I think the only implementation signature that will work is:

const fn: A = (...args: any[]) => {}

You'd then have to test the type of each argument yourself and figure out what the meaning of each one is and which call signature was used. And yeah, that's gonna suck.

const fn: A = (...args: any[]) => {
    if (args.length === 2 && typeof args[0] === 'string' && typeof args[1] === 'function') {
        // (message: string, callback: CustomCallBackFunction): void;
        const [message, callback] = args as [string, CustomCallBackFunction]
    } else if (args.length === 3 && typeof args[0] === 'string' && !Array.isArray(args[1]) && typeof args[2] === 'function') {
        // (message: string, meta: any, callback: CustomCallBackFunction): void;
        const [message, meta, callback] = args as [string, any, CustomCallBackFunction]
    } else {
        // etc...
    }
}

Playground

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM