Как передать необязательные параметры, опуская некоторые другие необязательные параметры?


282

Учитывая следующую подпись:

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

Как я могу вызвать функцию, error() не указав titleпараметр, а установив, autoHideAfterчтобы сказать 1000?

Ответы:


308

Как указано в документации , используйте undefined:

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

class X {
    error(message: string, title?: string, autoHideAfter?: number) {
        console.log(message, title, autoHideAfter);
    }
}

new X().error("hi there", undefined, 1000);

Ссылка на игровую площадку .


6
@ BBi7 Я думаю, вы неправильно поняли документацию. ?Добавляется в функции определения , но речь идет о фактически вызова функции.
— Томас

Привет @ Томас Я полностью понимаю документацию и знаю, что вы должны добавить? после параметра в определении функции. Но в связи с вызовом функции с необязательным параметром (ами) я бы предположил, что передача не определена, если это не применимо. Обычно я пытаюсь найти способы сделать необязательный параметр (и) в качестве конечного (ых) параметра (ов), чтобы я мог просто не передавать против undefined. Но, очевидно, если у вас их много, вам нужно будет передать неопределенное или что-то неправдивое. Я не уверен, что я имел в виду, когда я первоначально отправил. Это означает, что я не знаю, было ли это отредактировано, но то, что я вижу сейчас, правильно.
— BBi7

2
@ BBi7 Не было недавних изменений. Ладно, не бери в голову :) (Обратите внимание, что вы на самом деле должны пройти, undefinedчтобы получить то же поведение, что и пропустить аргумент целиком. Просто «все неправдивое» не сработает, потому что TypeScript фактически сравнивает с тем, void 0что является более безопасным способом записи) undefined. )
— Томас

71

К сожалению, в TypeScript нет ничего подобного (подробнее здесь: https://github.com/Microsoft/TypeScript/issues/467 )

Но чтобы обойти это, вы можете изменить свои параметры на интерфейс:

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

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

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

Не могли бы вы сказать, могу ли я вызвать метод error как этот, error ({message: 'test'}), я думаю, мы не можем, поэтому error ({message: 'test', autoHideAFter: undefined}), но то, что я ожидаю, является ошибкой (сообщением). Если я не передавал другие параметры, он должен принимать значения из параметров по умолчанию.
— Cegone

37

Вы можете использовать необязательную переменную с помощью ?или, если у вас есть несколько необязательных переменных ..., например:

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

В приведенном выше:

  • name необходимо
  • country является обязательным и имеет значение по умолчанию
  • address необязательно
  • hobbies массив необязательных параметров

2
Разве хобби не должно быть напечатано как массив?
— ProgrammerPer

4
В этом ответе есть полезная информация, но она не отвечает на вопрос. Вопрос в том, как я вижу, как можно обойти / пропустить несколько необязательных параметров и установить только конкретные.
— MaxB

2
страна не обязательна, это необязательный параметр, имеющий значение по умолчанию «CA» вместо неопределенного. если это требуется, то какой смысл предоставлять значение по умолчанию?
— Ананд Бхушан

19

Другой подход:

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

Поэтому, если вы хотите опустить параметр title, просто отправьте данные следующим образом:

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

Я бы предпочел эту опцию, потому что позволяет мне добавить больше параметров, не отправляя другие.


Как бы вы также передали значение по умолчанию title?
— Дан Даскалеску

13

Это почти то же самое, что и ответ @Brocco, но с небольшим поворотом: только передавать необязательные параметры в объекте. (А также сделать объект params необязательным).

Это в конечном итоге напоминает ** kwargs Python, но не совсем.

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:');

5

Вы можете указать несколько сигнатур методов на интерфейсе, а затем иметь несколько перегрузок методов для метода класса:

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
    }
}

Теперь все это будет работать:

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);

... и errorметод INotificationServiceбудет иметь следующие параметры:

Перегрузка intellisense

Игровая площадка


9
Просто замечание, которое я бы рекомендовал против этого, и вместо этого передал бы объект и поместил эти параметры в качестве свойств этого объекта ... это намного меньше работы, и код будет более читабельным.
— Дэвид Шеррет

2

Вы можете создать вспомогательный метод, который принимает один параметр объекта на основе аргументов ошибки.

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

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

-1

Вы можете попытаться установить заголовок на ноль.

Это сработало для меня.

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

3
Это будет работать, поскольку, если параметр функции имеет значение по умолчанию, когда вы отправляете ноль в этот параметр функции, не будет установлено значение по умолчанию
— Okan SARICA

-2

Вы можете сделать это без интерфейса.

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

используйте ?оператор в качестве необязательного параметра.


но это не позволяет вам указать messageиautoHideAfter
— Simon_Weaver

3
Вы не отвечаете на вопрос или не читали его. Он хочет знать, как вызвать метод с несколькими необязательными параметрами, без необходимости указывать первый необязательный параметр, если он хочет ввести только второй.
— Грегфр
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.