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

我是打字新手,我有两门课,在家长课上我有:

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 返回的函数有调用签名吗?我想我误解了函数类型的一些重要问题,但我不知道它是什么。

谢谢!

248982 次浏览

它返回的函数有一个调用签名,但是您通过在其签名中添加 : any告诉 Type 脚本完全忽略这一点。

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

在您的代码中:

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

我觉得你想要的是:

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)。你真正要做的是说: 这是一个函数,它提供了一个属性名,将返回一个允许你改变属性的函数。

makePropSetter上的 <T>允许您将该函数锁定到特定类型。子类构造函数中的 <boolean>实际上是可选的。因为您要赋值给 toggleBody,而且它已经完全指定了类型,所以 TS 编译器将能够自己解决这个问题。

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

我们来分析一下:

  1. 错误说

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

  2. 密码:

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

它与这些线条有关:

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

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

额外详情:

“调用”意味着调用或应用函数。

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

“ type”在这一行 public toggleBody: string中声明

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

换句话说,错误在于说

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

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

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

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

例如:

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


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

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

我得到了相同的错误消息。在我的案例中,我无意中将 ES6export default function myFunc语法与 const myFunc = require('./myFunc');语法混淆了。

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

当您向某个对象请求一个值时,如果将括号放在最后,就像函数调用一样,但是没有结束括号就可以正确地检索到该值时,可能会导致此错误。例如,如果您正在访问的是类型脚本中的属性“ get”。

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


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


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