如何在省略其他可选参数的同时传递可选参数?


280

给出以下签名:

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

如何调用error() 指定title参数而是设置autoHideAfter为的函数1000

Answers:


306

根据文档中的说明,使用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我认为您误解了文档。将?其添加到函数定义中,但问题是关于实际调用函数。
托马斯

嗨@Thomas我完全理解文档,并且知道您必须添加吗?在函数定义中的参数之后。但是,与使用可选参数调用函数有关,我假设如果不适用,则传递未定义。我通常会尝试寻找一些方法来将可选参数作为结束参数,这样我就无法通过vs. undefined。但是显然,如果您有很多,那么您就需要传递未定义的或不真实的内容。我不确定最初发布时指的是什么。意思是我不知道它是否被编辑过,但是我现在看到的正确无误。
BBi7

2
@ BBi7最近没有编辑。好的,没关系,然后:)(请注意,实际上您必须通过undefined以具有与完全省去参数相同的行为。仅“任何不真实的内容”将不起作用,因为TypeScript 实际上是比较void 0安全的书写方式undefined。 )
托马斯(Thomas

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”,而不是未定义。如果需要,那么提供默认值有什么意义?
阿南德·布


13

这几乎与@Brocco的答案相同,但略有不同:仅在对象中传递可选参数。(并且还将params对象设为可选)。

最终有点像Python的** kwargs,但不完全是。

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将具有以下选项:

过载智能

操场


9
只是需要注意的一点是,我建议您反对这样做,而是传入一个对象并将这些参数作为属性放在该对象上……这省去了很多工作,并且代码更易读。
David Sherret

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

您可以尝试将title设置为null。

这对我有用。

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

3
这将起作用,因为如果在向该函数参数发送null时该函数参数具有默认值,则不会将该参数设置为默认值
Okan SARICA

-2

您可以在没有界面的情况下执行此操作。

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

使用?运算符作为可选参数。


但是,这不允许您使用任何方式进行指定messageautoHideAfter
Simon_Weaver

3
您没有回答问题或没有阅读问题。他想知道如何调用具有多个可选参数的方法,而只想输入第二个可选参数而不必指定第一个可选参数。
格雷格夫(Gregfr),
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.