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

g.p*_*dou 238 typescript

鉴于以下签名:

export interface INotificationService {
    error(message: string, title?: string, autoHideAfter?: number);
}
Run Code Online (Sandbox Code Playgroud)

如何调用函数error()而不指定title参数,但将autoHideAfter设置为1000?

Tho*_*mas 257

文档中所述,使用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);
Run Code Online (Sandbox Code Playgroud)

游乐场链接.

  • @ BBi7我觉得你误解了文档.函数_definition_中添加了`?`,但问题是关于实际_calling_函数. (6认同)
  • @BBi7 最近没有编辑。好吧,没关系 :) (请注意,您实际上必须传递 `undefined` 以获得与完全省略参数相同的行为。只是“任何不真实的东西”都行不通,因为 TypeScript [实际上](https:// www.typescriptlang.org/play/#src=function%20foo(x%3A%20number%20%3D%200)%20%7B%0A%7D) 与 `void 0` 相比,这是一种更安全的书写方式 `未定义`。) (2认同)

Bro*_*cco 62

不幸的是,在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});
Run Code Online (Sandbox Code Playgroud)


Has*_*sef 35

您可以使用可选变量,?或者如果您有多个可选变量...,例如:

function details(name: string, country="CA", address?: string, ...hobbies: string) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

在上面:

  • name 是必须的
  • country 是必需的,并具有默认值
  • address 是可选的
  • hobbies 是一组可选参数

  • 这个答案中有一个有用的信息,但它没有回答这个问题。问题是,在我看来,如何绕过/跳过几个可选参数并仅设置特定参数。 (4认同)
  • 国家/地区不是必需的,它是一个可选参数,默认值为“CA”而不是未定义。如果需要的话提供默认值有什么意义? (3认同)
  • 兴趣爱好不应该作为数组输入吗? (2认同)

Gab*_*ada 14

另一种方法是:

error(message: string, options?: {title?: string, autoHideAfter?: number});
Run Code Online (Sandbox Code Playgroud)

因此,当您想省略title参数时,只需发送如下数据:

error('the message', { autoHideAfter: 1 })
Run Code Online (Sandbox Code Playgroud)

我宁愿使用此选项,因为它允许我添加更多参数而不必发送其他参数。

  • @DanDascalescu `...,选项?:{标题?:字符串} = {标题:“我的默认值”},...` (5认同)
  • 您如何将默认值传递给“title”? (3认同)

Mon*_*pit 10

这与@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:');
Run Code Online (Sandbox Code Playgroud)


Dav*_*ret 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
    }
}
Run Code Online (Sandbox Code Playgroud)

现在所有这些都可行:

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);
Run Code Online (Sandbox Code Playgroud)

...并且error方法INotificationService将具有以下选项:

过载智能感知

操场

  • 只是注意我会建议反对这个,而是传入一个对象并将这些参数作为属性放在该对象上......这样做的工作少得多,而且代码更具可读性. (7认同)