2016-09-25 55 views
26

我是全新的打字稿,我有两个类。在父类中我有:错误:无法调用其类型缺少呼叫签名的表达式

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

两个相册更多>>暂和ShowLess给我的错误,

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

谢谢!

+1

'togglrBody'不应该是一个字符串,因为您希望它是一个函数 – eavidan

+0

@eavidan是它是一个实际返回布尔值的函数。我原本以为它会返回一个字符串。那我该怎么改变它? – Justin

+0

无论setProp如何返回,看起来像'(val:T)=> T' – eavidan

回答

16

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

不要这样做。

+0

好的进度,谢谢!现在我得到“错误TS2322:类型'(val:T)=> T'不能分配到类型'boolean'。”如果我删除:any。我想这就是为什么我添加了:任何在第一位。我实际上仍然得到原始错误。 – Justin

+0

如果我这样做,并将'public toggleBody:boolean;'更改为'public toggleBody:any;'它的工作原理。 – Justin

+1

@Justin你为什么期望别的什么?你声称'this.toggleBody'应该返回'boolean',但这与你赋给它的'setProp'的返回值不一致。你似乎只是随机地抛出类型而不考虑你实际想要发送和返回的内容。 – jonrsharpe

10

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

在您的代码:

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

3

我想你想要的是:

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尊重相同的签名。

相关问题