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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39691889/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:48:58  来源:igfitidea点击:

Error: Cannot invoke an expression whose type lacks a call signature

javascriptangularjstypescripttypes

提问by Justin

I am brand new to typescript, and I have two classes. In the parent class I have:

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

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

In the child class I have:

在儿童班我有:

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

Both showMore and ShowLess give me the error, "Cannot invoke an expression whose type lacks a call signature."

showMore 和 ShowLess 都给我错误,“无法调用类型缺少调用签名的表达式。”

But the function that setProp returns DOES have a call signature, I think? I think I'm misunderstanding something important about typings of functions, but I don't know what it is.

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

Thanks!

谢谢!

采纳答案by SLaks

The function that it returns has a call signature, but you told Typescript to completely ignore that by adding : anyin its signature.

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

Don't do that.

不要那样做。

回答by basarat

"Cannot invoke an expression whose type lacks a call signature."

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

In your code :

在您的代码中:

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

You have public toggleBody: string;. You cannot call a stringas a function. Hence errors on : this.toggleBody(true);and this.toggleBody(false);

你有public toggleBody: string;。您不能将 astring作为函数调用。因此错误:this.toggleBody(true);this.toggleBody(false);

回答by Taysky

Let's break this down:

让我们分解一下:

  1. The error says

    Cannot invoke an expression whose type lacks a call signature.

  2. The code:

  1. 错误说

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

  2. 编码:

The problem is in this line public toggleBody: string;&

问题出在这一行public toggleBody: string;&

it's relation to these lines:

它与这些行的关系:

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

Your saying toggleBodyis a stringbut then your treating it like something that has a call signature(i.e. the structure of something that can be called: lambdas, proc, functions, methods, etc. In JS just function tho.). You need to change the declaration to be public toggleBody: (arg: boolean) => boolean;.

你的说法toggleBody是 astring但是你把它当作有 acall signature的东西(即可以调用的东西的结构:lambdas、proc、函数、方法等。在 JS 中只是函数 tho。)。您需要将声明更改为public toggleBody: (arg: boolean) => boolean;.

Extra Details:

额外细节:

"invoke" means your calling or applying a function.

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

"an expression" in Javascript is basically something that produces a value, so this.toggleBody()counts as an expression.

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

"type" is declared on this line public toggleBody: string

“类型”在这一行声明 public toggleBody: string

"lacks a call signature" this is because your trying to call something this.toggleBody()that doesn't have signature(i.e. the structure of something that can be called: lambdas, proc, functions, methods, etc.) that can be called. You said this.toggleBodyis something that acts like a string.

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

In other words the error is saying

换句话说,错误是说

Cannot call an expression (this.toggleBody) because it's type (:string) lacks a call signature (bc it has a string signature.)

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

回答by Andrew Miner

I think what you want is:

我想你想要的是:

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

The important change is in setProp(i.e., makePropSetterin the new code). What you're really doing there is to say: this is a function, which provided with a property name, will return a function which allows you to change that property.

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

The <T>on makePropSetterallows you to lock that function in to a specific type. The <boolean>in the subclass's constructor is actually optional. Since you're assigning to toggleBody, and that already has the type fully specified, the TS compiler will be able to work it out on its own.

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

Then, in your subclass, you call that function, and the return type is now properly understood to be a function with a specific signature. Naturally, you'll need to have toggleBodyrespect that same signature.

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

回答by Gunar Gessner

It means you're trying to call something that isn't a function

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

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

回答by Afshin Ghazi

Add a type to your variable and then return.

为变量添加一个类型,然后返回。

Eg:

例如:

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

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

=> Important part is adding the string[] type etc:

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

回答by Charlie Weems

I had the same error message. In my case I had inadvertently mixed the ES6 export default function myFuncsyntax with const myFunc = require('./myFunc');.

我有同样的错误信息。就我而言,我无意中将 ES6export default function myFunc语法与const myFunc = require('./myFunc');.

Using module.exports = myFunc;instead solved the issue.

使用module.exports = myFunc;,而不是解决问题。

回答by StackOverflowUser

This error can be caused when you are requesting a value from something and you put parenthesis at the end, as if it is a function call, yet the value is correctly retrieved without ending parenthesis. For example, if what you are accessing is a Property 'get' in Typescript.

当您从某事物中请求一个值并且将括号放在末尾时可能会导致此错误,就好像它是一个函数调用一样,但该值在没有结束括号的情况下被正确检索。例如,如果您正在访问的是 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;
};