Xsmael
Xsmael

Reputation: 3952

Why does typescript allow default parameters before required parameters?

i just noticed , that this function (using default params) doesn't cause error on compilation.

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

but this function (using optional params) does.

function buildAddress(address1?: string, address2: string) {
        displayAddress( address1 +' '+ address2);
    }

why is it so ?

i'm really surprised of this behavior, is that normal ? does it have any benefit ? is this a feature or a bug ?

Upvotes: 4

Views: 1702

Answers (1)

Nitzan Tomer
Nitzan Tomer

Reputation: 164337

Have you tried to use the first version without passing the first argument?

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

buildAddress("address2");

Results in:

Supplied parameters do not match any signature of call target

If you put the default value for the 2nd parameter though:

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

It works.

Adding default value for the first parameter only helps you in case you pass undefined:

buildAddress(undefined, "address2");

As it compiles to:

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

So in reality if you're doing this then the first parameter isn't optional at all, you must pass a value, and you only get the default value if you pass undefined.
But the compiler won't complain about the function signature because the first parameter has a value for sure, but in your 2nd function, since the first param is optional the compiler complains.


Edit

This behvior can be used to safe guard against undefined values, for example:

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

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

buildAddress(getAddress1(), "address 2");

I'm not sure if this is by design or just a byproduct, but it's useful in certain cases.

Upvotes: 6

Related Questions