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

时间:2016-09-25 21:10:47

标签: javascript angularjs typescript types

我是打字稿的新手,我有两个班级。在父类我有:

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都给我错误,&#34;无法调用类型缺少调用签名的表达式。&#34;

但是我认为setProp返回DOES的函数有一个调用签名?我认为我误解了一些关于功能类型的重要事项,但我不知道它是什么。

谢谢!

8 个答案:

答案 0 :(得分:51)

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

不要这样做。

答案 1 :(得分:27)

  

&#34;无法调用类型缺少调用签名的表达式。&#34;

在您的代码中:

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;。您无法将string作为函数调用。因此错误:this.toggleBody(true);this.toggleBody(false);

答案 2 :(得分:15)

让我们分解一下:

  1. 错误提示

      

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

  2. 代码:

问题出在此行public toggleBody: string;

与以下几行有关:

...
return this.toggleBody(true);
...
return this.toggleBody(false);
  1. 结果:

您说的toggleBodystring,但随后您将其视为具有call signature的事物(即可以称为的事物的结构:lambda,proc,函数,方法等等。在JS中,仅可以使用tho。)。您需要将声明更改为public toggleBody: (arg: boolean) => boolean;

其他详细信息:

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

Javascript中的“表达式”基本上是产生值的东西,因此this.toggleBody()被视为表达式。

在此行public toggleBody: string上声明

“类型”

“缺少呼叫签名”,这是因为您试图呼叫没有签名的this.toggleBody()(即可以被调用的事物的结构:lambda,proc,函数,方法等)。可以称为。您说this.toggleBody就像字符串一样。

换句话说,错误在说

  

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

答案 3 :(得分:6)

我认为你想要的是:

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

重要更改位于setProp(即新代码中的makePropSetter)。你真正在做的是说:这是一个带有属性名称的函数,它将返回一个允许你改变那个属性的函数。

<T>上的makePropSetter允许您将该功能锁定到特定类型。子类的构造函数中的<boolean>实际上是可选的。由于您要分配给toggleBody,并且已经完全指定了类型,因此TS编译器将能够自行完成它。

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

答案 4 :(得分:0)

这意味着您正在尝试调用不是函数的东西

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

答案 5 :(得分:0)

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

例如:

const myVariable : string [] = ['hello', 'there'];

const result = myVaraible.map(x=> {
  return
  {
    x.id
  }
});

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

答案 6 :(得分:0)

我有同样的错误信息。就我而言,我无意间将ES6 export default function myFunc语法与const myFunc = require('./myFunc');混合在一起。

使用module.exports = myFunc;解决了该问题。

答案 7 :(得分:0)

当您从某物请求一个值并将括号放在最后时,可能会导致此错误,就好像它是一个函数调用一样,但是正确地检索了该值而没有结束括号。例如,如果您要访问的是Typescript中的“获取”属性。

private IMadeAMistakeHere(): void {
    let mynumber = this.SuperCoolNumber();
}

private IDidItCorrectly(): void {
    let mynumber = this.SuperCoolNumber;
}

private get SuperCoolNumber(): number {
    let response = 42;
    return response;
};