为什么TypeScript在必需参数后需要可选参数?

时间:2017-10-26 15:56:26

标签: javascript typescript

这有效:

public console(message: string | undefined, suppressLevel: boolean) {}

但这并不是:

public console(message?: string, suppressLevel: boolean) {}

考虑到?似乎基本上是| undefined的简写(当你在VS Code中鼠标悬停时它就是这样说的),为什么TypeScript会有所区别?您可以明确地传入undefined以获取可选参数,它与在最后未指定它的情况相同。

4 个答案:

答案 0 :(得分:4)

最重要的是,这是一个javascript事实,通过强烈输入一个函数签名使其变得更加明确。

函数参数在参数列表中按位置绑定。第一个传递的参数绑定到第一个参数。第二个传递的参数绑定到第二个参数。等等。使用 end 处的可选参数,当参数列表太短时,javascript引擎知道将结束参数绑定到undefined。然而,调用很短,那就是有多少终结参数为undefined

如果可选参数可能位于中间或开头,那么调用站点上的信息就不足以知道哪些参数应绑定到哪些参数。

function fn(a?: number, b: number) { /* ... */ }

fn(42);

如果fn的签名有效,fn(42)将不明确。 b是否应42与[{1}} a绑定?或undefined a与[{1}}左42绑定(因此是类型错误?)在这种特殊情况下,您可能希望打字稿类型检查器为ASSUME没有错误,而是尝试最难找到对调用的有效解释(b得到undefined的那个),但这将是一个更昂贵的重载解析算法,仍然会有案例这是不明确的,规则太复杂而无法使用(即b42

Javascript,通过使用尾随参数的位置参数可选,并使用Typescript允许我们明确地注释允许的签名重载,在表达性,合理性(类型检查器的性能)和错误避免之间取得很大的平衡。

如果重载解析以这种方式更灵活,那么它必须考虑更多有效的调用,这可能实际上是错误。或者它会给函数体带来负担,以完全处理所有变量,例如使所有参数组合成为彼此之间的联合类型,然后必须在代码中取消它们,使其更难阅读。

答案 1 :(得分:2)

public console(message: string | undefined, suppressLevel: boolean) {}

使用竖线(|)运算符声明类型 stringuddefined的参数。有关详细信息,请参阅union types

public console(suppressLevel: boolean, message?: string) {}

声明一个as per docs need to follow required parameters

的可选参数
  

任何可选参数都必须遵循必要的参数。

因此,在实践中,可选的字符串参数IS确实是一个类型为string或undefined(或取决于您的设置为null)的参数,这两个是遵循不同规则的不同语法。强制可选参数在必需参数之后增加可读性和功能性,而typescript不能仅仅将union类型视为可选参数,因为它们是两个截然不同的东西。因此存在差异。

答案 2 :(得分:2)

?不是string | undefined的简写。它是一个可选参数。含义 - 您可以传递预期的值类型,也可以不传递。

相比之下,

string | undefined意味着您必须显式传递一个字符串或未定义的值。 可能未定义,但参数仍然存在。

在可选属性之后传递属性是自相矛盾的 - 你无法设置它,因为设置它会意味着在它之前设置一个,这意味着它的前身不是可选的!

答案 3 :(得分:1)

  

在TypeScript中,假定函数需要每个参数。这并不意味着它不能被赋予null或未定义,而是在调用函数时,编译器将检查用户是否为每个参数提供了值。    - Optional and default parameters

可选参数意味着您不必传入任何内容。你的工会示例说它必须是一个字符串或undefined primitive

class Lorem{
  public unionType(required:boolean,message: string | undefined) { }
  public optional(required:boolean, message?: string) {}
}

let lorem = new Lorem();
lorem.unionType(true);//Error missing second parameter message
lorem.unionType(true,undefined);//have to explicitly pass in undefined
lorem.optional(false);//A-OK

由于你可以为可选参数传递任何内容,因此它们必须是参数列表中的最后一个。

  

您可以显式传入undefined以获取可选参数和   它与最后没有指定它一样。

但是你不能省略对于union参数的undefined传递,所以它们不是完全相同的东西。