2017-08-13 127 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

这是一个很好的说明,但是(正如你所说),它仍然是一个谜,为什么他们首先做出了设计决定。多数民众赞成我真的想要达到底部... –