2012-10-12 38 views
10

如果我有這樣的功能:如何註釋TypeScript中的遞歸類型?

function say(message: string) { 
    alert(message); 
    return say; 
} 

它的有趣特性,我可以連鎖調用它:

say("Hello,")("how")("are")("you?"); 

編譯器會如果我通過將號碼生成警告第一個電話,但它會讓我把數字放入隨後的電話。

say("Hello")(1)(2)(3)(4) 

什麼類型的註釋,我需要添加到say功能,使編譯器生成警告,當我在無效的類型傳遞到鏈式調用?

回答

18

引用自身的類型必須有名稱。例如,

interface OmegaString { 
    (message: string): OmegaString; 
} 

,那麼你可以註解sayOmegaString

function say(message: string): OmegaString { 
    alert(message); 
    return say; 
} 

然後將下面的代碼將類型檢查。

say("Hello,")("how")("are")("you?"); 

但下面不會,

say("Hello")(1)(2)(3)(4) 
+0

能否請您解釋爲何它必須有一個名字? –

+2

@OldrichSvec除非有一些特殊的自引用類型關鍵字,否則您需要一個名稱才能引用它,而IMO經常不會使用這個關鍵字來增加值。 –

+0

@OldrichSvec彼得是完全正確的。遞歸類型需要能夠引用自身。給它一個名字可以讓它引用它自己。 – chuckj

0

可鏈接的方法

當您正在使用的,而不是一個函數的類,你可以使用this類型來表達事實的方法返回它在(鏈接方法)上調用的實例。

沒有this

class StatusLogger { 
    log(message: string): StatusLogger { ... } 
} 
// this works 
new ErrorLogger().log('oh no!').log('something broke!').log(':-('); 

class PrettyLogger extends StatusLogger { 
    color(color: string): PrettyLogger { ... } 
} 
// this works 
new PrettyLogger().color('green').log('status: ').log('ok'); 
// this does not! 
new PrettyLogger().log('status: ').color('red').log('failed'); 

隨着this

class StatusLogger { 
    log(message: string): this { ... } 
} 
class PrettyLogger extends StatusLogger { 
    color(color: string): this { ... } 
} 
// this works now! 
new PrettyLogger().log('status:').color('green').log('works').log('yay'); 

可鏈接的功能

當一個函數是可鏈接的,你可以用一個接口類型是:

function say(text: string): ChainableType { ... } 
interface ChainableType { 
    (text: string): ChainableType; 
} 
say('Hello')('World'); 

與屬性/方法可鏈接的功能

如果一個函數具有其他屬性或方法(如jQuery(str) VS jQuery.data(el)),您可以鍵入函數本身作爲接口:

interface SayWithVolume { 
    (message: string): this; 
    loud(): this; 
    quiet(): this; 
} 

const say: SayWithVolume = ((message: string) => { ... }) as SayWithVolume; 
say.loud =() => { ... }; 
say.quiet =() => { ... }; 

say('hello').quiet()('can you hear me?').loud()('hello from the other side');