typescript 打字稿:通过传入命名参数的构造函数创建类?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45507428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:47:24  来源:igfitidea点击:

Typescript: Create class via constructor passing in named parameters?

typescriptnamed-parameters

提问by Martin

I have a class where I have the constructor defined with 3 parameters which are all optional. I was hoping to be able to pass in named parameters so I don't need to pass in undefined.

我有一个类,其中的构造函数定义了 3 个参数,这些参数都是可选的。我希望能够传入命名参数,所以我不需要传入 undefined。

constructor(year?: number,
            month?: number,
            date?: number)

I was hoping to create an intance of the class like so

我希望像这样创建一个类的实例

  const recurrenceRule = new MyNewClass(month: 6)

but it didn't work and i tried

但它没有用,我试过了

  const recurrenceRule = new MyNewClass(month = 6)

and that didn't work.

那没有用。

The only way i got it to work was either

我让它工作的唯一方法是

  const recurrenceRule = new MyNewClass(undefined, 4)

or

或者

  const recurrenceRule = new MyNewClass(, 4)

But it seems so messy, I was hoping to pass in named arguments and becasue they are all optional I should be able to just pass in 1 - right ?

但它看起来很乱,我希望传入命名参数,因为它们都是可选的,我应该能够传入 1 - 对吗?

回答by SVSchmidt

You can use Object destructuring introduced in ES6 to archieve the desired behavior: reference. TypeScript is able to transpile this feature for usage with ES5 to target older browsers. However, as of ES6, this is also perfectly valid JavaScript.

您可以使用 ES6 中引入的对象解构来归档所需的行为:引用。TypeScript 能够将此功能转译为与 ES5 一起使用,以针对较旧的浏览器。然而,从 ES6 开始,这也是完全有效的 JavaScript。

Basically, it looks like this: constructor({ year, month, day})and is invoked, for instance, as new Bar({ year: 2017 }). Then you can access yearas a variable within the constructor, e.g. for assigning this.year = year.

基本上,它看起来像这样:constructor({ year, month, day})并且被调用,例如,作为new Bar({ year: 2017 })。然后您可以year在构造函数中作为变量访问,例如分配this.year = year.

More interesting than that is the usage with default values, e.g.

比这更有趣的是使用默认值,例如

constructor({ year = new Date().getFullYear(), 
              month = new Date().getMonth(), 
              day = new Date().getDay()
            } = {})

which allows invoking the constructor with 0, 1, 2 or 3 parameters respectively (see snippet below).

它允许分别使用 0、1、2 或 3 个参数调用构造函数(参见下面的代码片段)。

The somewhat cryptic = {}is for the case when you create a new instance without any parameters. First, {}is used as the default value for the parameter object. Then, since yearis missing, the default value for that one is added, then for month and for day respectively.

有点神秘的= {}是当您创建一个没有任何参数的新实例时。首先,{}用作参数对象的默认值。然后,由于year缺少,添加了那个的默认值,然后分别为月和日。

For usage with TypeScript, you can, of course, add additional typings,

为了与 TypeScript 一起使用,您当然可以添加其他类型,

constructor({ year = new Date().getFullYear(),
              month = new Date().getMonth(),
              day = new Date().getDay()
}: { year?: number, month?: number, day?: number } = {}) { 
    ...                
}

Although this reallylooks cryptic.

虽然这看起来真的很神秘。

class Bar {
  constructor({ year, month, day }) {
    this.year = year;
    this.month = month;
    this.day = day;
  }
  
  log () {
    console.log(`year: ${this.year}, month: ${this.month}, day: ${this.day}`);
  }
}

new Bar({ day: 2017 }).log();

class Foo {
  constructor({ year = new Date().getFullYear(), 
                month = new Date().getMonth(), 
                day = new Date().getDay()
              } = {}) {
    this.year = year;
    this.month = month;
    this.day = day;
  }
  
  log () {
    console.log(`year: ${this.year}, month: ${this.month}, day: ${this.day}`);
  }
}

console.log('with default value:');
new Foo().log();
new Foo({ day: 2 }).log();
new Foo({ day: 2, month: 8 }).log();
new Foo({ year: 2015 }).log();

回答by elm

class Bar {
  constructor({a, b}: {a?: number, b?: number}) {}
}

new Bar({b: 1})

For more information, see ES6 Object Destructuring with functions.

有关更多信息,请参阅ES6 Object Destructuring with functions

回答by Paul Grimshaw

Simple parameter:

简单参数:

constructor (private recurrenceSettings: {year?: number, month?: number, date?: number})

The private keyword instantiates argument as an instance variable, saving you needing to instantiate in the constructor. Can also be publicif you want to instatiate public properties.

private 关键字将参数实例化为实例变量,省去了在构造函数中实例化的需要。public如果您想实例化公共属性,也可以是。

Use like this:

像这样使用:

const recurrenceRule = new MyClass({month: 12})

Or use destructuring (usage same as above):

或者使用解构(用法同上):

constructor({day, month, year}: {day?: number, month?: number, year?: number})

The above version loses the ability to use the private/public shortcut for instance variables though (see https://github.com/Microsoft/TypeScript/issues/5326).

尽管上面的版本失去了对实例变量使用私有/公共快捷方式的能力(请参阅https://github.com/Microsoft/TypeScript/issues/5326)。