【发布时间】:2020-09-26 16:05:53
【问题描述】:
我创建了一个函数,它使用扩展运算符来接受具有不同数量参数的重载。不幸的是,打字稿说函数的参数之一是不可调用的。以下是我所指的示例。
type Arguments=[{():void}]|[string,{():void}]|[string,number,{():void}];
function overload(...args:Arguments){
//Do stuff depending on number of arguments
if(args.length===2)console.log(args[0]);
if(args.length===3)console.log(args[0],args[1]);
args[args.length-1](); //TS error here
}
//An example of how I'd like to call it
overload(()=>console.log(`I'm always the last..`));
overload('example',()=>console.log(`..and I'm a function..`));
overload('example',1,()=>console.log(`..that can be called`));
最后一个参数总是一个函数,因为元组[{():void}]|[string,{():void}]|[string,number,{():void}]每个都以{():void}结尾。因此它可以像args[args.length-1]();一样被调用,但我明白了:
此表达式不可调用。并非所有类型为 'string |号码 | (() => void)' 是可调用的。类型“字符串”没有调用 签名.ts(2349)
我的问题是:无论如何,我如何告诉 typescript - 上面显示的数组的最后一项是我可以调用的函数?这是做这种事情的最佳方式吗?关于如何以更好的方法获得与上述相同结果的任何建议?
我试过了:
//NOPE
function overload(...args:Arguments):void{
/* ... */
if(typeof args[args.length-1]==='function'){
args[args.length-1]();
}
}
//NOPE
function overload(...args:[{():void}]):void;
function overload(...args:[string,{():void}]):void;
function overload(...args:[string,number,{():void}]):void;
function overload(...args:[{():void}]|[string,{():void}]|[string,number,{():void}]):void{
/* ... */
args[args.length-1]();
}
我知道我可以做这样的事情来解决这个问题:
function overload(...args:Arguments){
/* ... */
const last=args[args.length-1] as {():void};
last();
}
但我只调用了数组的最后一项。我不想仅仅为了让它工作而制作一个特殊的变量,这也是我编写类型的原因——为了摆脱错误而不是创建新的“假”,对吧?这是args.length-1 TS 无法处理的某种未知值吗,但如果是这样,为什么 TS 假定它是“字符串 |号码 | (() => void)' 类型?
代码按预期工作(用纯 javascript 编写)。原始代码比这个高级一点,因此,我对其进行了简化,在我看来它并没有改变它的主要含义。如果重要的话,我正在使用 typescript 3.9.5。
【问题讨论】:
标签: typescript