Optional function parameters are indicated with a question mark (?) after the parameter name. The same applies to optional properties in objects (interfaces or types).
function greet(name?: string) { console.log(`Hello, ${name ?? 'stranger'}`); } greet(); // Hello, stranger greet('John'); // Hello, John
interface User { id: number; nickname?: string; } const u1: User = { id: 1 }; const u2: User = { id: 2, nickname: 'Bob' };
Nuances:
If a function is declared with an optional parameter of type string (function fn(x?: string)), can it be explicitly called with undefined? What is the difference between fn() and fn(undefined)?
Answer: Yes, it can be called with undefined: fn(undefined) and fn() — the result is the same, but inside the function, x will be received as undefined. However, if a default value is defined in the signature:
function fn(x: string = 'demo') { console.log(x); } fn(); // demo fn(undefined); // demo fn('abc'); // abc
If the argument is not declared as optional (there's no ? or default value), calling fn() will be a compilation error.
Story
In the user interface, the property phone: string (without ?) was specified, but it was forgotten when creating an object instance. As a result, the TypeScript compiler started complaining about the missing required property. A temporary solution was to add phone: undefined, but this contradicted the type, as string !== undefined, leading to even more validation errors.
Story
Several optional parameters were defined in a function, but they were not placed at the end of the argument list. TypeScript threw an error, and rearranging the parameters changed the order of correspondence between passed values and parameters, causing confusion and incorrect function behavior.
Story
Optional fields in interfaces were forgotten when describing the data type for an external API (for example, client's last name? string), causing these fields to stop being received when the schema changed on one side, while on the other side, the code started to fail when trying to read them without checking for undefined.