2016-09-25 51 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尊重相同的簽名。

相關問題