为什么打字稿允许默认参数先于必需参数?

Xsm*_*ael 3 compiler-errors function optional-parameters default-parameters typescript

我刚刚注意到,此函数(使用默认参数)不会在编译时引起错误。

function buildAddress(address1 = 'N/A', address2: string) {
        displayAddress( address1 +' '+ address2);
    }
Run Code Online (Sandbox Code Playgroud)

但是此功能(使用可选参数)可以。

function buildAddress(address1?: string, address2: string) {
        displayAddress( address1 +' '+ address2);
    }
Run Code Online (Sandbox Code Playgroud)

为什么会这样呢?

我真的对这种行为感到惊讶,这很正常吗?有什么好处吗?这是功能还是错误?

Nit*_*mer 5

您是否尝试过使用第一个版本而不传递第一个参数?

function buildAddress(address1: string = 'N/A', address2: string) {
    console.log(address1, address2);
}

buildAddress("address2");
Run Code Online (Sandbox Code Playgroud)

结果是:

提供的参数与呼叫目标的任何签名都不匹配

如果您将第二个参数的默认值设置为:

function buildAddress(address1: string , address2: string = 'N/A') {
    console.log(address1, address2);
}
Run Code Online (Sandbox Code Playgroud)

有用。

为第一个参数添加默认值仅在通过时才有帮助undefined

buildAddress(undefined, "address2");
Run Code Online (Sandbox Code Playgroud)

编译为:

function buildAddress(address1, address2) {
    if (address1 === void 0) { address1 = 'N/A'; }
    console.log(address1, address2);
}
Run Code Online (Sandbox Code Playgroud)

因此,实际上,如果执行此操作,则第一个参数根本不是可选的,您必须传递一个值,而如果传递,则仅获得默认值undefined
但是编译器不会抱怨函数签名,因为第一个参数肯定有一个值,但是在您的第二个函数中,因为第一个参数是可选的,所以编译器会抱怨。


编辑

此行为可用于安全防范undefined值,例如:

function buildAddress(address1 = 'N/A', address2: string) {
    displayAddress(address1 + ' ' + address2);
}

function getAddress1(): string {
    // logic here, might return undefined
}

buildAddress(getAddress1(), "address 2");
Run Code Online (Sandbox Code Playgroud)

我不确定这是设计使然还是副产品,但是在某些情况下它很有用。