在下面的 TypeScript 中,两个函数是相同的,除了我试图在demoTwo 中显式声明返回类型。返回类型是一个函数,它本身将一个函数作为输入。我的问题是为什么我必须给出由whyThis表示的参数名称,因为它永远不会被使用?如果没有该位置的内容,代码将无法编译。
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);
Run Code Online (Sandbox Code Playgroud)
要清楚我在这里问的是 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)
}
}
Run Code Online (Sandbox Code Playgroud)
如果我们并排设置demoTwo的声明,我们有:
function demoTwo(): (whyThis:() => string) => void { //TS
def demoTwo(): (() => String) => Unit = { //Scala
Run Code Online (Sandbox Code Playgroud)
唯一的主要区别是 TS 在原因位置需要一些东西,而 Scala 不需要。为什么会这样?
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);
};
}
Run Code Online (Sandbox Code Playgroud)
编辑:所以你是正确的,参数在运行时从不使用,但是这些参数在编译时显示(取决于你的编辑器)。如果您不添加调用签名,编辑器将从运行时参数中推断出一个并在编译时显示。
您可以将调用签名视为与其他人交流您的代码如何使用以及参数代表什么的一种方式,其编写方式非常易于使用您的代码的人理解。
以下是 Visual Studio 在您的函数上方悬停时显示的内容,这些代码定义在调用这些函数时也会显示在 VSCode 和其他编辑器中:
演示一:
演示二:
我认为混淆源于定义签名的方式。注意下面的3个签名
(number) => Void
(x : number) => Void
(_ : number) => Void
Run Code Online (Sandbox Code Playgroud)
最后两个是接受类型为 number 的参数的 void 函数的签名。然而,第一个函数采用 Any 类型的参数网络,并带有名称编号。因此该语言需要一个名称后跟一个类型,如果省略该类型,则假定为 Any 类型。
所以,
(() => string) => void
Run Code Online (Sandbox Code Playgroud)
无效,因为 '() => string' 不是有效名称,编译器在尝试解析它时感到困惑。
最短的形式将使用'_ : type'。
但我同意省略名称并且只使用类型或名称是可选的会更好。我不确定他们为什么做出这个设计决定,也许是为了避免与现有的 JavaScript 箭头函数(没有类型)混淆。