2017-08-13 125 views
0

在TypeScript中,下面兩個函數都是相同的,但我試圖在demoTwo中明確聲明返回類型。返回類型是一個函數,它本身將函數作爲輸入。我的問題是爲什麼我必須給參數名稱whyThis,因爲它永遠不會被使用?沒有這個位置的東西就不會編譯代碼。TypeScript中lambda返回類型的簽名

function demoOne() { 
    return function(input:() => string) : void { 
     var result = input(); 
     console.log("Foo:",result); 
    } 
} 

function demoTwo(): (whyThis:() => string) => void { 
    return function(input:() => string) : void { 
     var result = input(); 
     console.log("Bar:",result); 
    } 
} 

var sampleInput =() => "wibble"; 
demoOne()(sampleInput); 
demoTwo()(sampleInput); 

要弄清楚我問這裏是Scala中的等效代碼:

object Program { 
    def demoTwo(): (() => String) => Unit = { 
    def tmp(input:() => String): Unit = { 
     val result = input() 
     println("Bar: " + result) 
    } 
    return tmp 
    } 
    def main(args: Array[String]): Unit = { 
    val sampleInput =() => "wibble" 
    demoTwo()(sampleInput) 
    } 
} 

如果我們並排設置demoTwo方的聲明,我們有:

function demoTwo(): (whyThis:() => string) => void { //TS 
def demoTwo(): (() => String) => Unit = { //Scala 

唯一的主要區別是TS需要的東西在爲什麼這個位置和Scala沒有。爲什麼會這樣呢?

回答

1

無論您是否決定使用它們,typescript中的所有函數參數都需要有一個名稱。你所添加的是呼叫簽名,它不是在運行時使用的,但是在編寫代碼時會對你有所幫助。

如果你看一下生成的JavaScript文件兩者的例子,他們都將輸出完全相同的代碼:

function demoOne() { 
    return function (input) { 
     var result = input(); 
     console.log("Foo:", result); 
    }; 
} 
function demoTwo() { 
    return function (input) { 
     var result = input(); 
     console.log("Bar:", result); 
    }; 
} 

編輯:那麼,你是在正確的參數運行過程中從未使用過,但是這些參數在編譯時會顯示(取決於您的編輯器)。如果您不添加呼叫簽名,則編輯器將從運行時參數中推斷出一個,並在編譯時顯示此信息。

您可以將您的簽名作爲與其他人溝通的方式,將您的代碼如何使用以及參數代表的方式傳遞給他人,這些代碼非常易於理解。

這裏是Visual Studio中顯示你上面的功能用吸塵器吸塵時,這些代碼定義也VSCode和其他編輯器顯示調用這些函數時:

演示一個:

enter image description here

演示2 :

enter image description here

+0

確實如此。但是我的問題與你的陳述「你是否決定使用它們」有關。在這種情況下,參數** whyThis **永遠不能使用,所以這只是對Typescript規範的忽略,或者是我有沒有看到它的某種目的? –

+0

我已經編輯了一些答案,試圖回答你的問題,讓我知道如果該主題仍不清楚。 – hagner

+0

謝謝。出於某種原因無法看到圖像。另外,我不認爲你對我的要求很清楚。已經添加了希望澄清事情的代碼的Scala版本。 –

1

我覺得混亂幹從簽名的定義方式。請注意以下3個簽名

(number) => Void 
(x : number) => Void 
(_ : number) => Void 

最後兩個是採用類型編號參數的void函數的簽名。然而,第一個函數使用Any類型的參數,並帶有一個名稱編號。因此,該語言需要一個名稱,後跟一個類型,如果該類型被省略,則假定爲任何類型。

所以,

(() => string) => void 

是無效的「()=>字符串」不是一個有效的名稱和編譯器感到困惑試圖解析它是這樣。

最短的形式將使用'_:type'。

但我同意,將名稱省略,只使用類型或名稱是可選的更好。我不確定他們爲什麼做出這個設計決定,或許是爲了避免與現有的JavaScript箭頭函數(無類型)混淆。

+0

這是一個很好的說明,但是(正如你所說),它仍然是一個謎,爲什麼他們首先做出了設計決定。多數民衆贊成我真的想要達到底部... –