TypeScript Optional Parameters

In standard JavaScript, every function parameter is essentially optional; if you don't provide a value, it simply becomes undefined. TypeScript, however, is much stricter to help prevent bugs. By default, TypeScript expects you to provide an argument for every parameter defined in a function.

To give developers more flexibility, TypeScript provides optional parameters. These allow you to define parameters that may or may not be passed when the function is called. You can mark a parameter as optional by appending a ? symbol after the parameter name in the function signature.

 

Syntax for Optional Parameters

function functionName(param1: type, param2?: type): returnType {
  // function body
}

In this syntax, param1 is required, while param2 is optional. If the caller omits param2, its value inside the function will be undefined.

Watch Out: Optional parameters must always be defined after any required parameters. You cannot have an optional parameter followed by a required one, as this would make it impossible for the TypeScript compiler to determine which argument corresponds to which parameter.

Example of Optional Parameters

Let's look at a practical scenario: a function that formats a user's full name. Sometimes a user might not have a middle name, so we make that parameter optional.

function formatName(firstName: string, lastName: string, middleName?: string): string {
  if (middleName) {
    return `${firstName} ${middleName} ${lastName}`;
  }
  return `${firstName} ${lastName}`;
}

console.log(formatName("John", "Doe"));                 // Output: John Doe
console.log(formatName("Alice", "Smith", "Marie"));    // Output: Alice Marie Smith

In this example:

  • The middleName parameter is optional.
  • Inside the function, we check if middleName exists before using it. This prevents "undefined" from appearing in our string output.
Common Mistake: Forgetting to check for undefined. If you treat an optional parameter as if it’s always there (e.g., calling middleName.length without a check), TypeScript will throw an error because the value might be undefined.

Default Values for Optional Parameters

Sometimes, instead of leaving a parameter as undefined, you want it to have a fallback value. This is known as a default parameter. In TypeScript, parameters with default values are automatically treated as optional.

function sendEmail(to: string, subject: string = "No Subject"): string {
  return `Sending email to ${to} with subject: ${subject}`;
}

console.log(sendEmail("[email protected]"));                        // Output: Sending email to [email protected] with subject: No Subject
console.log(sendEmail("[email protected]", "Project Update"));      // Output: Sending email to [email protected] with subject: Project Update

In this case, if the subject is not provided, it defaults to "No Subject". This is often cleaner than using the ? syntax because it removes the need for manual undefined checks inside your function logic.

Best Practice: Use default values (param = value) instead of optional markers (param?) when there is a sensible "fallback" logic. This makes your code more predictable and reduces conditional checks.

Optional Parameters with Rest Parameters

You can combine optional parameters with rest parameters (which collect multiple arguments into an array). This is useful for functions that take a few specific inputs followed by a variable list of items.

function buildTask(title: string, priority?: string, ...tags: string[]): string {
  let task = `Task: ${title}`;
  if (priority) task += ` [Priority: ${priority}]`;
  if (tags.length > 0) task += ` Tags: ${tags.join(", ")}`;
  
  return task;
}

console.log(buildTask("Fix Bug"));                                     // Output: Task: Fix Bug
console.log(buildTask("Deploy", "High", "DevOps", "Urgent"));         // Output: Task: Deploy [Priority: High] Tags: DevOps, Urgent

The hierarchy must always follow this order:

  1. Required parameters
  2. Optional parameters
  3. Rest parameters

Function Overloading with Optional Parameters

Function overloading allows you to define multiple ways a function can be called. While optional parameters are great for simple cases, overloading provides better type safety and documentation for complex API designs.

// Overload signatures
function getMessage(id: number): string;
function getMessage(id: number, format: string): string;

// Implementation signature
function getMessage(id: number, format?: string): string {
  if (format === "json") {
    return JSON.stringify({ messageId: id, content: "Hello World" });
  }
  return `Message ID: ${id}`;
}

console.log(getMessage(101));            // Output: Message ID: 101
console.log(getMessage(102, "json"));    // Output: {"messageId":102,"content":"Hello World"}

By using overloading, you tell the TypeScript compiler exactly which combinations of arguments are valid. This provides better autocompletion for other developers using your code.

Developer Tip: If your function starts to have more than 3 optional parameters, consider passing a single "options" object instead. This makes the function call much more readable: createUser({ name: 'John', age: 30, role: 'Admin' }).

 

Summary

Optional parameters in TypeScript bridge the gap between JavaScript’s flexibility and TypeScript’s safety. They allow you to build functions that handle missing data gracefully. Remember to always place optional parameters at the end of your parameter list and use default values whenever a fallback is available to keep your code clean and robust.