web-dev-qa-db-fra.com

Combinaison du raccourci Propriétés du paramètre avec Destructuring in TypeScript

MODIFIER

Je me suis connecté un problème sur le référentiel Github de TypeScript et ils acceptent les PR pour l'implémenter.


Dans TypeScript, lorsque nous voulons créer automatiquement des propriétés dans notre classe à partir de la définition du constructeur, nous pouvons tirer parti de la méthode abrégée Propriétés du paramètre, par exemple:

class Person {
    constructor(public firstName : string, public lastName : number, public age : number) {

    }
}

Et puis, le Javascript transpilé sera:

var Person = (function () {
    function Person(firstName, lastName, age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
    return Person;
})();

Mais si nous voulons recevoir un objet dans notre constructeur, ce serait quelque chose comme:

interface IPerson {
    firstName : string,
    lastName : string,
    age: number
}

class Person {
    constructor(person : IPerson) {
        this.firstName = person.firstName;
        this.lastName = person.lastName;
        this.age = person.age;
    }
}

Depuis TypeScript 1.5, nous pouvons tirer parti de la déstructuration, par exemple:

class Person {
    constructor({firstName, lastName, age} : {firstName: string, lastName: string, age: number}) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
}

Question : Comment combiner le raccourci Propriétés du paramètre et la destruction dans TypeScript?

J'ai essayé de définir public avant la définition de l'objet, par exemple:

class Person {
    constructor(public {firstName, lastName, age} : {firstName: string, lastName: string, age: number}) {

    }
}

J'ai essayé de le définir avant chaque variable, par exemple:

class Person {
    constructor({public firstName, public lastName, public age} : {firstName: string, lastName: string, age: number}) {

    }
}

Mais je n'ai eu aucun succès. Des pensées?

20
Buzinas

Il n'y a pas actuellement de moyen de faire ce raccourci, donc le plus proche que vous puissiez obtenir est de déclarer les propriétés en long et d'assigner les variables à partir de l'affectation de déstructuration:

class Person {
    firstName: string;
    lastName: string;
    age: number;

    constructor({firstName, lastName, age} : {firstName: string, lastName: string, age: number}) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
}

Si vous faites cela ... vous déciderez probablement simplement d'accepter une IPerson et d'affecter ses membres sans utiliser de déstructuration dans le constructeur.

3
Fenton

Une autre stratégie consiste à utiliser la possibilité d’affecter une variable d’un nom différent. Cela réduit une répétition dans le constructeur.

class Person {
    firstName: string;
    lastName: string;
    age: number;

    constructor(args: { firstName: string, lastName: string, age: number, }) {
        ({
            firstName: this.firstName,
            lastName: this.lastName,
            age: this.age,
        } = args);
    }
}

Vous pouvez également déplacer l'une des définitions du constructeur vers une interface.

interface PersonConstructorArgs {
    firstName: string;
    lastName: string;
    age: number;
}
class Person {
    firstName: string;
    lastName: string;
    age: number;

    constructor(args: PersonConstructorArgs) {
        ({
            firstName: this.firstName,
            lastName: this.lastName,
            age: this.age,
        } = args);
    }
}

Cela sera utile lorsque vous avez une hiérarchie.

interface PersonConstructorArgs {
    firstName: string;
    lastName: string;
    age: number;
}
class Person {
    firstName: string;
    lastName: string;
    age: number;

    constructor(args: PersonConstructorArgs) {
        ({
            firstName: this.firstName,
            lastName: this.lastName,
            age: this.age,
        } = args);
    }
}
interface EmployeeConstructorArgs extends PersonConstructorArgs {
    manager: Person;
}
class Employee extends Person {
    manager: Person;

    constructor(args: EmployeeConstructorArgs) {
        super(args);
        ({
            manager: this.manager,
        } = args);
    }
}
1
Schmalls

Si vous avez accès à Object.assign, cela fonctionne:

class PersonData {
  firstName: string
  constructor(args : PersonData) {
    Object.assign(this, args)
  }
}

class Person extends PersonData{}

Mais notez que les nouvelles instances seront remplies par n'importe quoi dans les arguments - vous ne pouvez pas effacer uniquement les clés que vous souhaitez utiliser.

1
elm