Borislav Hadzhiev
Sun Feb 27 2022ยท4 min read
Photo by NeONBRAND
Use a question mark to set an optional parameter in a function in TypeScript,
e.g. function sum(a: number, b?: number) {}
. If set to optional, the parameter
can have a type of undefined
or the specified type, because unspecified
parameters get the value undefined
.
// โ Optional parameter without default value function sum(a: number, b?: number) { if (b) { return a + b; } return a + a; } console.log(sum(10)); // ๐๏ธ 20 console.log(sum(10, 3)); // ๐๏ธ 13 // โ Optional parameter with default value function multiply(a: number, b = 10) { return a * b; } console.log(multiply(5)); // ๐๏ธ 50 console.log(multiply(5, 2)); // ๐๏ธ 10 // โ Optional property for object parameter function getEmployee({ name = 'Tom', salary, }: { name?: string; // ๐๏ธ Mark optional salary: number; }) { return { name, salary }; } // ๐๏ธ {name: 'Tom', salary: 100} console.log(getEmployee({ salary: 100 }));
In the first example, we marked the parameter b
as
optional.
This means that the function can be invoked without providing the parameter,
which would set the value of the b
argument to undefined
.
Not providing the parameter and providing a parameter with a value of
undefined
is the same in JavaScript (and TypeScript).
// โ Optional parameter without default value function sum(a: number, b?: number) { if (b) { return a + b; } return a + a; } // โ These 2 lines are the same console.log(sum(10)); // ๐๏ธ 20 console.log(sum(10, undefined)); // ๐๏ธ 20
Note that a required parameter cannot follow an optional parameter.
// โ๏ธ Error: A required parameter cannot // follow an optional parameter.ts(1016) function sum(a?: number, b: number) { }
You should always specify the optional parameters at the end of the function's parameter list.
You can also set a function parameter to optional implicitly - by providing a default value for it.
// โ Optional parameter with default value function multiply(a: number, b = 10) { return a * b; } console.log(multiply(5)); // ๐๏ธ 50 console.log(multiply(5, 2)); // ๐๏ธ 10
Notice that we didn't have to use a question mark ?
to set the parameter b
as optional.
You should always set default values at the end of a function's parameter list.
// ๐๏ธ default value at beginning function multiply(a = 10, b: number) { return a * b; } // โ๏ธ Error: Expected 2 arguments, but got 1.ts(2554) console.log(multiply(5)); // ๐๏ธ NaN // โ Works console.log(multiply(undefined, 5)); // ๐๏ธ 50
Even though we provided a default value for the first parameter the function takes, it's not optional, because there is a second parameter that is required.
undefined
for the specific parameter.When you have a function that takes an object as a parameter, you might need to set properties in the object to optional or set the entire object to optional.
Here is an example that sets a property in an object parameter to optional.
function getEmployee({ name = 'Tom', // ๐๏ธ default value salary, }: { name?: string; // ๐๏ธ Mark optional salary: number; }) { return { name, salary }; } // ๐๏ธ {name: 'Tom', salary: 100} console.log(getEmployee({ salary: 100 }));
We set the name
property in the object to optional and provided a default
value for it.
Let's look at how you would set the entire object parameter to optional.
function getEmployee({ name, salary, }: { name?: string; salary?: number } = {}) { return { name, salary }; } // ๐๏ธ {name: undefined, salary: undefined} console.log(getEmployee());
We used a question mark to set all properties in the object to optional and provided an empty object as the default value.
Here is an example of how you would also provide default values for the object's properties.
function getEmployee( { name, salary }: { name?: string; salary?: number } = { name: 'Tom', salary: 100, }, ) { return { name, salary }; } // ๐๏ธ {name: 'Tom', salary: 100} console.log(getEmployee());
Notice that we have marked all properties on the object as optional and are passing a default value for the entire object, not for each property.
This is an important distinction, because if you mark all properties as optional and set default values for them, you would still have to pass an empty object to the function.
function getEmployee({ name = 'Tom', salary = 100, }: { name?: string; salary?: number; }) { return { name, salary }; } // โ๏ธ Error: Expected 1 arguments, but got 0.ts(2554) console.log(getEmployee()); // โ Works console.log(getEmployee({}));
In the example above, we set all of the properties in the object to optional and provided default values for them.
However, we are still required to pass the object when calling the function, because we didn't set a default value for the object itself.
If your function declaration looks too busy, you can use a type alias.
type GetEmployeeParams = { name?: string; salary: number; }; function getEmployee({ name = 'Tom', salary }: GetEmployeeParams) { return { name, salary }; } console.log(getEmployee({ salary: 100 }));
This is a bit easier to read, as we can clearly see that the name
property is
set to optional and the function expects to be called with an object of type
GetEmployeeParams
.