Javascript 错误:无法调用其类型缺少调用签名的表达式
我对typescript是全新的,我有两门课。在父类中,我有: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; }; } }
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
向变量添加类型,然后返回
例如:
=>重要的部分是添加字符串[]类型等:我收到了相同的错误消息。在我的例子中,我无意中将ES6export 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;
};