[typescript] How to pass optional parameters while omitting some other optional parameters?

Given the following signature:

export interface INotificationService {
    error(message: string, title?: string, autoHideAfter?: number);
}

How can I call the function error() not specifying the title parameter, but setting autoHideAfter to say 1000?

This question is related to typescript

The answer is


You could try to set title to null.

This worked for me.

error('This is the ',null,1000)

You can create a helper method that accept a one object parameter base on error arguments

 error(message: string, title?: string, autoHideAfter?: number){}

 getError(args: { message: string, title?: string, autoHideAfter?: number }) {
    return error(args.message, args.title, args.autoHideAfter);
 }

Unfortunately there is nothing like this in TypeScript (more details here: https://github.com/Microsoft/TypeScript/issues/467)

But to get around this you can change your params to be an interface:

export interface IErrorParams {
  message: string;
  title?: string;
  autoHideAfter?: number;
}

export interface INotificationService {
  error(params: IErrorParams);
}

//then to call it:
error({message: 'msg', autoHideAfter: 42});

You can do this without an interface.

class myClass{
  public error(message: string, title?: string, autoHideAfter? : number){
    //....
  }
}

use the ? operator as an optional parameter.


Another approach is:

error(message: string, options?: {title?: string, autoHideAfter?: number});

So when you want to omit the title parameter, just send the data like that:

error('the message', { autoHideAfter: 1 })

I'd rather this options because allows me to add more parameter without having to send the others.


This is almost the same as @Brocco 's answer, but with a slight twist: only pass optional parameters in an object. (And also make params object optional).

It ends up being kind of like Python's **kwargs, but not exactly.

export interface IErrorParams {
  title?: string;
  autoHideAfter?: number;
}

export interface INotificationService {
  // make params optional so you don't have to pass in an empty object
  // in the case that you don't want any extra params
  error(message: string, params?: IErrorParams);
}

// all of these will work as expected
error('A message with some params but not others:', {autoHideAfter: 42});
error('Another message with some params but not others:', {title: 'StackOverflow'});
error('A message with all params:', {title: 'StackOverflow', autoHideAfter: 42});
error('A message with all params, in a different order:', {autoHideAfter: 42, title: 'StackOverflow'});
error('A message with no params at all:');

You can specify multiple method signatures on the interface then have multiple method overloads on the class method:

interface INotificationService {
    error(message: string, title?: string, autoHideAfter?: number);
    error(message: string, autoHideAfter: number);
}

class MyNotificationService implements INotificationService {
    error(message: string, title?: string, autoHideAfter?: number);
    error(message: string, autoHideAfter?: number);
    error(message: string, param1?: (string|number), param2?: number) {
        var autoHideAfter: number,
            title: string;

        // example of mapping the parameters
        if (param2 != null) {
            autoHideAfter = param2;
            title = <string> param1;
        }
        else if (param1 != null) {
            if (typeof param1 === "string") {
                title = param1;
            }
            else {
                autoHideAfter = param1;
            }
        }

        // use message, autoHideAfter, and title here
    }
}

Now all these will work:

var service: INotificationService = new MyNotificationService();
service.error("My message");
service.error("My message", 1000);
service.error("My message", "My title");
service.error("My message", "My title", 1000);

...and the error method of INotificationService will have the following options:

Overload intellisense

Playground


you can use optional variable by ? or if you have multiple optional variable by ..., example:

function details(name: string, country="CA", address?: string, ...hobbies: string) {
    // ...
}

In the above:

  • name is required
  • country is required and has a default value
  • address is optional
  • hobbies is an array of optional params