Javascript 错误:无法调用其类型缺少调用签名的表达式

Javascript 错误:无法调用其类型缺少调用签名的表达式,javascript,angularjs,typescript,types,Javascript,Angularjs,Typescript,Types,我对typescript是全新的,我有两门课。在父类中,我有: abstract class Component { public deps: any = {}; public props: any = {}; public setProp(prop: string): any { return <T>(val: T): T => { this.props[prop] = val; return val; }; } }

我对typescript是全新的,我有两门课。在父类中,我有:

abstract class Component {
  public deps: any = {};
  public props: any = {};

  public setProp(prop: string): any {
    return <T>(val: T): T => {
      this.props[prop] = val;
      return val;
    };
  }
}
class Post extends Component {
  public toggleBody: string;

  constructor() {
    this.toggleBody = this.setProp('showFullBody');
  }

  public showMore(): boolean {
    return this.toggleBody(true);
  }

  public showLess(): boolean {
    return this.toggleBody(false);
  }
}
showMore和ShowLess都给出了一个错误:“无法调用类型缺少调用签名的表达式。”

但是我认为setProp返回的函数确实有一个调用签名?我想我误解了一些关于函数类型的重要信息,但我不知道它是什么


谢谢

它返回的函数有一个调用签名,但是您告诉Typescript通过在签名中添加
:any
来完全忽略它

“无法调用其类型缺少调用签名的表达式。”

在代码中:

class Post extends Component {
  public toggleBody: string;

  constructor() {
    this.toggleBody = this.setProp('showFullBody');
  }

  public showMore(): boolean {
    return this.toggleBody(true);
  }

  public showLess(): boolean {
    return this.toggleBody(false);
  }
}

您有
public-toggleBody:string。不能将
字符串
作为函数调用。因此出现错误:
this.toggleBody(true)
此.toggleBody(false)

我想你想要的是:

abstract class Component {
  public deps: any = {};
  public props: any = {};

  public makePropSetter<T>(prop: string): (val: T) => T {
    return function(val) {
      this.props[prop] = val
      return val
    }
  }
}

class Post extends Component {
  public toggleBody: (val: boolean) => boolean;

  constructor () {
    super()
    this.toggleBody = this.makePropSetter<boolean>('showFullBody')
  }

  showMore (): boolean {
    return this.toggleBody(true)
  }

  showLess (): boolean {
    return this.toggleBody(false)
  }
}
抽象类组件{
公共部门:any={};
公共道具:any={};
公共makePropSetter(prop:string):(val:T)=>T{
返回函数(val){
this.props[prop]=val
返回值
}
}
}
类Post扩展组件{
公共toggleBody:(val:boolean)=>boolean;
构造函数(){
超级()
this.toggleBody=this.makePropSetter('showFullBody'))
}
showMore():boolean{
返回此.toggleBody(true)
}
showLess():boolean{
返回此.toggleBody(false)
}
}
重要的更改在
setProp
中(即新代码中的
makePropSetter
)。你真正要做的是说:这是一个函数,它提供了一个属性名,将返回一个函数,允许你更改该属性

makePropSetter
上的
允许您将该函数锁定为特定类型。子类的构造函数中的
实际上是可选的。由于您正在分配给
toggleBody
,并且已经完全指定了类型,TS编译器将能够自己计算出来

然后,在子类中调用该函数,返回类型现在被正确理解为具有特定签名的函数。当然,您需要让
toggleBody
尊重相同的签名。

我们来分析一下:

  • 错误是

    无法调用其类型缺少调用签名的表达式

  • 守则:

  • 问题出在这一行
    publictoglebody:string&

    这与以下几行有关:

    ...
    return this.toggleBody(true);
    ...
    return this.toggleBody(false);
    
  • 结果是:
  • 你说的
    toggleBody
    是一个
    字符串
    ,但是你把它当作一个具有
    调用签名的东西(即可以调用的东西的结构:lambdas、proc、函数、方法等等,在JS中就是function tho)。您需要将声明更改为
    publictoglebody:(arg:boolean)=>boolean

    额外详细信息:

    “调用”是指调用或应用函数

    Javascript中的“表达式”基本上是生成值的东西,因此
    this.toggleBody()
    算作表达式

    “type”在此行声明
    public-toggleBody:string

    “缺少调用签名”这是因为您试图调用的东西
    this.toggleBody()
    没有可以调用的签名(即可以调用的东西的结构:lambdas、proc、函数、方法等)。你说的
    这个。toggleBody
    是一个类似字符串的东西

    换句话说,错误在于

    无法调用表达式(this.toggleBody),因为它的类型(:string)缺少调用签名(bc它有一个字符串签名)


    这意味着你试图调用的东西不是函数

    const foo = 'string'
    foo() // error
    

    向变量添加类型,然后返回

    例如:


    =>重要的部分是添加字符串[]类型等:

    我收到了相同的错误消息。在我的例子中,我无意中将ES6
    export default function myFunc
    语法与
    const myFunc=require('./myFunc')混合在一起


    使用
    module.exports=myFunc反而解决了这个问题。

    当您从某个对象请求一个值,并将括号放在末尾时,可能会导致此错误,就好像它是一个函数调用,但在没有结束括号的情况下正确检索该值一样。例如,如果您正在访问的是Typescript中的属性“get”

    private IMadeAMistakeHere(): void {
        let mynumber = this.SuperCoolNumber();
    }
    
    private IDidItCorrectly(): void {
        let mynumber = this.SuperCoolNumber;
    }
    
    private get SuperCoolNumber(): number {
        let response = 42;
        return response;
    };
    

    好的,谢谢!现在,如果删除:any,我会得到“error TS2322:Type'(val:T)=>T'不可分配给类型'boolean'。”。我想这就是为什么我加了一句:首先是任何。实际上,我仍然会得到原始错误
    公共切换体:任意有效。@贾斯汀,你为什么还指望别的?您声明
    this.toggleBody
    应返回
    布尔值
    ,但这与您分配给它的
    setProp
    的返回值不一致。您似乎只是随意输入类型,而没有考虑实际要发送和返回的内容。@jornsharpe好的,是的,这很有意义。在本例中,它返回一个布尔值,但通常返回任意值。因此,我必须使用any?这个响应将受益于通过一个示例解释正确的做事方式。
    togglrBody
    不应该是字符串,因为您希望它是字符串function@eavidan是的,它是一个实际返回布尔值的函数。我原本以为它会返回一个字符串。那么我要把它改成什么呢?不管setProp返回什么,它看起来像
    (val:T)=>T
    ,这是最好的答案之一!我知道所有这些定义,但当我看到警告信息时,所有这些术语,在一个密集的句子中,对我混乱的大脑来说太多了。
    private IMadeAMistakeHere(): void {
        let mynumber = this.SuperCoolNumber();
    }
    
    private IDidItCorrectly(): void {
        let mynumber = this.SuperCoolNumber;
    }
    
    private get SuperCoolNumber(): number {
        let response = 42;
        return response;
    };