web-dev-qa-db-fra.com

Typescript: Créer une classe via un constructeur en passant des paramètres nommés?

J'ai une classe où j'ai le constructeur défini avec 3 paramètres qui sont tous facultatifs. J'espérais pouvoir passer des paramètres nommés afin de ne pas avoir besoin de passer non défini.

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

J'espérais créer une intance de la classe comme si

  const recurrenceRule = new MyNewClass(month: 6)

mais ça n'a pas marché et j'ai essayé

  const recurrenceRule = new MyNewClass(month = 6)

et cela n'a pas fonctionné.

Le seul moyen de le faire fonctionner était soit

  const recurrenceRule = new MyNewClass(undefined, 4)

ou

  const recurrenceRule = new MyNewClass(, 4)

Mais cela semble si compliqué, j’espérais passer des arguments nommés et parce qu’ils sont tous facultatifs, je devrais pouvoir simplement passer à 1 - non?

13
Martin

Vous pouvez utiliser la déstructuration des objets introduite dans ES6 pour obtenir le comportement souhaité: référence . TypeScript peut transpiler cette fonctionnalité pour pouvoir être utilisée avec ES5 afin de cibler des navigateurs plus anciens. Cependant, à partir de l'ES6, c'est également un JavaScript parfaitement valide.

En gros, il ressemble à ceci: constructor({ year, month, day}) et est appelé, par exemple, en tant que new Bar({ year: 2017 }). Ensuite, vous pouvez accéder à year en tant que variable dans le constructeur, par exemple. pour assigner this.year = year.

Plus intéressant que cela est l’utilisation avec default values ​​, par exemple.

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

ce qui permet d'appeler le constructeur avec respectivement 0, 1, 2 ou 3 paramètres (voir l'extrait de code ci-dessous).

Le = {} quelque peu cryptique est pour le cas où vous créez une nouvelle instance sans aucun paramètre. Tout d'abord, {} est utilisé comme valeur par défaut pour l'objet de paramètre. Ensuite, puisque year est manquant, la valeur par défaut pour celle-ci est ajoutée, puis pour mois et pour jour respectivement.

Pour une utilisation avec TypeScript, vous pouvez bien sûr ajouter des typages supplémentaires,

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

Bien que cette vraiment semble cryptique.

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

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

new Bar({b: 1})

Pour plus d'informations, voir Destruction d'objets ES6 avec des fonctions .

2
elm

Paramètre simple:

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

Le mot-clé private instancie l'argument en tant que variable d'instance, ce qui vous évite d'avoir à instancier dans le constructeur. Peut aussi être public si vous voulez instater des propriétés publiques.

Utilisez comme ceci:

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

Ou utilisez la déstructuration (utilisation identique à celle ci-dessus):

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

La version ci-dessus perd la possibilité d'utiliser le raccourci privé/public pour les variables d'instance (voir https://github.com/Microsoft/TypeScript/issues/5326 ).

0
Paul Grimshaw