2

我正在尝试在打字稿中实现下面显示的接口

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;
} 

这里 CustomCallBackFunction 定义

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

我无法用类实现接口。任何想法如何做到这一点。

这是用于方法重载例如,我有一个 B 类,其类型为 A 变量,其实现引用所有其他选项。

class B {
public c: A
}

然后我可以打电话

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

1 回答 1

1

可悲的是,实现此接口的唯一方法是使所有参数any

这个接口很像函数重载。这意味着实现函数必须采用一个参数,该参数是该位置参数的所有可能性的联合。

  1. 第一个参数是string, string, string,anyobject。所以类型是,string | object | any它简化为包括其他可能性。anyany

  2. 第二个参数CustomCallBackFunction | any | undefinedany

  3. 第三个参数可能是CustomCallBackFunction或 的第二个项目...meta: any[],所以同样,那个是any


因此,鉴于所有参数都必须是 type any并且可能有任意数量的参数,我认为唯一可行的实现签名是:

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

然后,您必须自己测试每个参数的类型,并弄清楚每个参数的含义以及使用了哪个调用签名。是的,那会很糟糕。

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...
    }
}

操场

于 2020-08-07T06:57:52.923 回答