我在一个类上有这个方法签名:
lock(key: string, opts: any, cb?: LMClientLockCallBack): void;
如果用户像这样使用它:
lock('foo', null, (err,val) => {
});
他们会得到正确的打字。但是,如果他们省略 options 参数并执行以下操作:
lock('foo', (err,val) => {
});
然后
tsc
将回调函数视为类型 any
, 像这样:![enter image description here](https://i.sstatic.net/ONspp.png)
有什么方法可以让用户避免将空对象或 null 作为第二个参数传递,并将回调转移过来?
我尝试将该方法重载为两个定义:
lock(key: string, cb: LMClientLockCallBack, n?: LMClientLockCallBack) : void;
lock(key: string, opts: any, cb?: LMClientLockCallBack) { ... }
但是还是编译不通过,出现了新问题:
![enter image description here](https://i.sstatic.net/Lktmo.png)
如果我尝试这个:
lock(key: string, cb: LMClientLockCallBack) : void;
lock(key: string, opts: any, cb?: LMClientLockCallBack) { ... }
我明白了:
![enter image description here](https://i.sstatic.net/rq2ED.png)
这个问题肯定有解决方案吗?
最佳答案
在 TypeScript 中重载方法时,实现不算作重载之一。因此,您应该创建三个函数定义:两个用于不同的重载,正如您已经完成的那样,第三个 - 带有可选参数和实际实现,它在您的代码中错误地连接到第二个重载定义。所以你会有:
lock(key: string, cb: LMClientLockCallBack) : void;
lock(key: string, opts: any, cb: LMClientLockCallBack): void;
lock(key: string, opts: any, cb?: LMClientLockCallBack) { ... }
因此,如果第二个参数是回调 - 用户将获得第一个重载类型,如果它是其他任何东西,但第三个参数是回调 - 第二个重载类型。但在这两种情况下,它们将调用相同的实现,就像在纯 JavaScript 中一样。
关于TypeScript 允许可选参数 - 重载方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51202569/