这有效:
public console(message: string | undefined, suppressLevel: boolean) {}
但这并不是:
public console(message?: string, suppressLevel: boolean) {}
考虑到?
似乎基本上是| undefined
的简写(当你在VS Code中鼠标悬停时它就是这样说的),为什么TypeScript会有所区别?您可以明确地传入undefined
以获取可选参数,它与在最后未指定它的情况相同。
答案 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
的那个),但这将是一个更昂贵的重载解析算法,仍然会有案例这是不明确的,规则太复杂而无法使用(即b
与42
)
Javascript,通过使用尾随参数的位置参数可选,并使用Typescript允许我们明确地注释允许的签名重载,在表达性,合理性(类型检查器的性能)和错误避免之间取得很大的平衡。
如果重载解析以这种方式更灵活,那么它必须考虑更多有效的调用,这可能实际上是错误。或者它会给函数体带来负担,以完全处理所有变量,例如使所有参数组合成为彼此之间的联合类型,然后必须在代码中取消它们,使其更难阅读。
答案 1 :(得分:2)
public console(message: string | undefined, suppressLevel: boolean) {}
使用竖线(|
)运算符声明类型 string
或uddefined
的参数。有关详细信息,请参阅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传递,所以它们不是完全相同的东西。