devstory

Propriétés dans TypeScript

  1. Qu'est-ce qu'un champ ?
  2. Private, Protected & Public Fields
  3. Qu'est-ce qu'une propriété ?
  4. Getter
  5. Setter

1. Qu'est-ce qu'un champ ?

Dans cette leçon, on abordera les propriétés dans TypeScript. Mais avant d'entrer dans le contenu principal, il est nécessaire de clarifier le concept de champs (field).
Un champ (field) est une variable déclarée directement dans une classe.
Consulter l'article sur les constructeurs pour comprendre comment TypeScript attribue des valeurs aux champs :
Dans le langage TypeScript, si vous pouvez accéder à un champ, vous pouvez obtenir sa valeur et lui attribuer une nouvelle valeur. Par exemple:
field_ex1.ts
class Person {
    name: string;
    gender: string;
    country?: string; // Allow null value.
    // Constructor
    constructor(name: string, gender: string, country?: string) {
        this.name = name;
        this.gender = gender;
        this.country = country;
    }
    // Method:
    selfIntroduce(): void {
        if (this.country) {
            console.log(`Hi, My name is ${this.name}, from ${this.country}`);
        } else {
            console.log(`Hi, My name is ${this.name}`);
        }
    }
}
function field_ex1_test() {
    var emma: Person = new Person('Emma', 'Female', 'USA'); // Create an object
    emma.selfIntroduce(); // Call method.

    var name = emma.name; // get the value of a field
    console.log(`emma.name: ${name}`);
    console.log(`emma.gender: ${emma.gender}`);
    console.log(`emma.country: ${emma.country}`);

    console.log(` --- Set new value to country field ---: `);
    emma.country = 'Canada'; // set new value to a field
    console.log(`emma.country: ${emma.country}`);
}  
// Call the function.
field_ex1_test();
Output:
Hi, My name is Emma, from USA
emma.name: Emma
emma.gender: Female
emma.country: USA
 --- Set new value to country field ---:
emma.country: Canada

2. Private, Protected & Public Fields

TypeScript antérieur à 3.8
TypeScript antérieur à 3.8 ne fournit pas encore les mots-clefs private, protected et public. Pour obtenir un champ privé, les programmeurs le nomment en commençant par un dièse ( # ). Ces champs ne sont accessibles qu'au sein de la classe qui les a définis.
field_private_ex1.ts
class Foo {
    #bar: string;

    constructor(bar: string) {
        this.#bar = bar;
    }
}
function field_private_ex1_test() {
    var foo: Foo = new Foo('Bar'); // Create an object

    foo.#bar; // Compile Error!!!!!!
}
TypeScript 3.8+
À partir de la version 3.8, TypeScript prend en charge les mots-clefs private, protected et public dans une déclaration de champ.
class Class_Name  {
   private field1: string;
   protected field2 : string;
   public field3 : string;
   field4 : string; // Default =  public
}
Modifier
Description
private
Le champ n'est accessible qu'à l'intérieur de la classe qui le définit.
protected
Le champ est accessible dans la classe qui le définit, ou dans des sous-classes.
public
Le champ est accessible partout.
Dans l'exemple ci-dessous, un champ est déclaré avec le mot-clef private, qui n'est pas accessible en dehors de la classe qui l'a défini.
field_private_ex2.ts
class Bar {
    private foo: string;

    constructor(foo: string) {
        this.foo = foo;
    }
}
function field_private_ex2_test() {
    var bar: Bar = new Bar('Foo'); // Create an object

    bar.foo; // Compile Error!!!!!!
}

3. Qu'est-ce qu'une propriété ?

En règle générale, lorsque vous avez accès à un champ quelque part, vous pouvez récupérer sa valeur et lui attribuer une nouvelle valeur.
La propriété est un concept similaire à un champ (field), mais il a des caractéristiques plus spéciales. La propriété est divisée en 3 types :
  • Read-only Property: Autoriser à accéder à sa valeur, mais pas à lui attribuer une nouvelle valeur.
  • Write-only Property: Autoriser à lui définir une nouvelle valeur. Cependant, essayer d'accéder à cette propriété obtiendra une valeur undefined.
  • Read/Write Property: Autoriser à accéder à la valeur actuelle et lui attribuer une nouvelle valeur.
Conformément à l'idée de conception de TypeScript, vous devez déclarer tous les champs de la classe avec le mot-clef private et utiliser des propriétés pour remplacer le rôle des champs dans la communication avec le monde extérieur.

4. Getter

La syntaxe Getter vous permet de définir une propriété qui autorise l'accès à sa valeur, mais ne peut pas lui définir une nouvelle valeur à moins que vous ne définissiez également un Setter pour cette propriété.
La syntaxe :
get property_name(): data_type {
     // code ...
     return a_value;
}
// Or:
[private, protected, public] get property_name(): data_type {
     // code ...
     return a_value;
}
Par exemple : La classe Employee ci-dessous permet d'accéder à la valeur de la propriété empId, mais ne permet pas de modifier la valeur de cette propriété.
property_getter_ex1.ts
class Employee {
    private _empId: number; // Field
    empName: string; // Field
    dept?: string; // Field

    constructor(empId: number, empName: string, dept: string) {
        this._empId = empId;
        this.empName = empName;
        this.dept = dept;
    }
    // Getter
    get empId(): number { // Property - empId
        return this._empId;
    }
    // Method:
    showInfo(): void {
        if (this.dept) {
            console.log(`Emp ID: ${this._empId}, Emp Name: ${this.empName}, Dept: ${this.dept}`);
        } else {
            console.log(`Emp ID:  ${this._empId}, Emp Name: ${this.empName}`);
        }
    }
}
function property_getter_ex1_test() {
    var tom: Employee = new Employee(2, "Tom", "IT");  // Create an object
    tom.showInfo(); // Call method.

    var empId = tom.empId; // get the value of a property
    console.log(`empId: ${empId}`);

    // Can not set new value to property - empId
    tom.empId = 2; // Compile Error!!!!!!!!!!!!!!!!!!!
}
// Call the function
property_getter_ex1_test();
Vous pouvez utiliser les mots-clefs private, protected ou public dans la définition de Getter.
// Getter
protected get empId(): number { // Property - empId
  return this._empId;
}

5. Setter

La syntaxe Setter vous permet de définir une propriété, vous permettant de lui affecter une nouvelle valeur. Cependant, sans le Getter, essayer d'accéder à cette propriété obtiendra une valeur undefined.
La syntaxe :
set property_name(new_value: data_type) {
     // code ...
}
// Or:
[private, protected, public] set property_name(new_value: data_type) {
     // code ...
}
Par exemple : La classe Staff a un Setter mais pas de Getter pour la propriété de salaire. Si vous essayez d'accéder à la valeur du salaire, le compilateur ne signalera pas d'erreur, mais la valeur est undefined.
property_setter_ex1.ts
class Staff {
    private _staffId: number; // Field
    staffName: string; // Field
    private _salary?: number; // Field

    constructor(staffId: number, staffName: string, salary: number) {
        this._staffId = staffId;
        this.staffName = staffName;
        this._salary = salary;
    }
    // Getter
    get staffId(): number { // Property - staffId
        return this._staffId;
    }
    // Setter
    set salary(salary: number) {
        this._salary = salary;
    }
    showInfo()  {
        console.log(`ID: ${this._staffId}, Name: ${this.staffName}, Salary: ${this._salary}`)
    }
}
function property_setter_ex1_test() {
    var tom: Staff = new Staff(2, "Tom", 2000);  // Create an object

    tom.showInfo();
    tom.salary = 3000; // Set new value to salary property
    tom.showInfo();
 
    // Try to access to 'salary' property of Staff class
    console.log(" --- Try to access to 'salary' property of Staff class --- ");
    var s = tom.salary; // No problem at Compile Time (!!!!!!!!!!!)
    console.log(`tom.salary = ${s}`); // underfined (!!!!!!!!!!!!!!!)
}
// Call the function
property_setter_ex1_test();
Output:
ID: 2, Name: Tom, Salary: 2000
ID: 2, Name: Tom, Salary: 3000
 --- Try to access to 'salary' property of Staff class ---
tom.salary = undefined
Vous pouvez utiliser les mots-clefs private, protected ou public dans la définition de Setter, sa signification est similaire à celle utilisée avec des champs.
// Setter
public set salary(salary: number) {
    this._salary = salary;
}