无法调用类型缺少调用签名的表达式...没有兼容的调用签名
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法调用类型缺少调用签名的表达式...没有兼容的调用签名相关的知识,希望对你有一定的参考价值。
我收到一个错误
Cannot invoke an expression whose type lacks a call signature ... has no compatible call signatures.
在我的一个方法上,我无法弄清楚如何解决它。我看过这个链接qazxsw poi
还有2个,但仍然无法弄明白
类型声明:
在我的班级,我有2个静态方法,看起来像这样
type ProcessMethods = "execute" | "execSpawn"
interface IDeferedCmd {
type: ProcessMethods,
cmd: string,
name: string,
resolve: IResolveFn,
reject: IRejectFn,
args?: Array<string>,
options?: object
}
并试图以动态方式调用它们,从而引发错误的第三种方法
static execute({cmd, name}: { cmd: string, name: string }): Promise<{
stdout: string;
stderr: string;
}>
static execSpawn({cmd, name, args , options }: { cmd: string, name: string, args: Array<string>, options: object }): Promise<NodeJS.ReadableStream>
而它自己的错误
无法调用类型缺少调用签名的表达式。输入'(({cmd,name}:{cmd:string; name:string;})=> Promise <{}>)| (({cmd,name,args,options} ...'没有兼容的调用签名.ProcessPoolExecutorfirstDeferedCmd.type; ~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
问题是这两个函数具有不同的签名,因此索引操作的结果将是两个签名的并集,根据定义它们是不可调用的。
您可以使用if (typeof firstDeferedCmd == "object" && ( firstDeferedCmd.type === "execute" || firstDeferedCmd.type === "execSpawn" )) {
ProcessPoolExecutor[firstDeferedCmd.type](firstDeferedCmd); // this line throw the error
}
方法Function
或call
,这些方法可以访问(因为它们在联合中的两个签名都是通用的)来调用函数,但缺点是丢失所有类型的安全性:
apply
你总是可以使用一个断言来使联合可以调用,但这并不比if (typeof firstDeferedCmd == "object" && ( firstDeferedCmd.type === "execute" || firstDeferedCmd.type === "execSpawn" )) {
ProcessPoolExecutor[firstDeferedCmd.type].call(ProcessPoolExecutor, firstDeferedCmd);
}
更安全:
call
您还可以使用两个检查来分离出两个不同的签名,这实际上暴露了您当前设计的一个问题:
if (typeof firstDeferedCmd == "object" && ( firstDeferedCmd.type === "execute" || firstDeferedCmd.type === "execSpawn" )) {
(ProcessPoolExecutor[firstDeferedCmd.type] as (cmd: IDeferedCmd) => Promise<{stdout: string;stderr: string;}> | Promise<NodeJS.ReadableStream>)(firstDeferedCmd);
}
我们可以通过更改function fn(firstDeferedCmd : IDeferedCmd){
if (typeof firstDeferedCmd == "object") {
if(firstDeferedCmd.type === "execute") {
return ProcessPoolExecutor[firstDeferedCmd.type](firstDeferedCmd);
}
if(firstDeferedCmd.type === "execSpawn") {
if(firstDeferedCmd.args){
return ProcessPoolExecutor[firstDeferedCmd.type](firstDeferedCmd); // error since there is no requirement if execSpawn is specified to also specify args
}
}
}
}
的定义来解决这个问题:
IDeferedCmd
以上是关于无法调用类型缺少调用签名的表达式...没有兼容的调用签名的主要内容,如果未能解决你的问题,请参考以下文章
Typescript中的“无法调用类型缺少调用签名的表达式”?
为啥 TypeScript 声称它“无法调用类型缺少调用签名的表达式”?