betacode

Свойства в TypeScript

  1. Что такое Field?
  2. Private, Protected & Public Fields
  3. Что такое Property?
  4. Getter
  5. Setter

1. Что такое Field?

В этом уроке мы обсудим property в TypeScript. Но прежде чем мы перейдем к основному содержанию, нам нужно уточнить концепцию полей (field).
Поле (field) - это переменная, объявленная непосредственно в классе.
Смотрите статью о конструкторах, чтобы понять, как TypeScript присваивает полям значения:
На языке TypeScript, если вы можете получить доступ к полю, вы можете получить его значение и установить для него новое значение. Например:
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 старше 3,8
TypeScript старше 3.8 еще не содержит ключевых слов private, protected и public. Чтобы иметь private field, программисты называют его, начиная с символа решетки (#). Доступ к этим полям возможен только в том классе, который их определил.
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+
Начиная с версии 3.8, TypeScript поддерживает ключевые слова private, protected и public в объявлении поля.
class Class_Name  {
   private field1: string;
   protected field2 : string;
   public field3 : string;
   field4 : string; // Default =  public
}
Modifier
Description
private
К полю можно получить доступ только в том классе, который его определяет.
protected
К полю можно получить доступ в классе, который его определяет, или в подклассах.
public
К полю можно получить доступ в любом месте.
В приведенном ниже примере поле объявляется с ключевым словом private, к которому нельзя получить доступ за пределами класса, который его определил.
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. Что такое Property?

В принципе, как только у вас есть доступ к какому-либо полю, вы можете получить его значение и присвоить ему новое значение.
Property - это понятие, похожее на поле (field), но у него больше особенностей. Property делится на 3 типа:
  • Read-only Property: Разрешает доступ к его значению, но не позволяет установить для него новое значение.
  • Write-only Property:Позволяет задать для него новое значение. Однако попытка получить доступ к этому property приведет к получению значения undefined.
  • Read/Write Property: Разрешает доступ к текущему значению и устанавливает для него новое значение.
Согласно идее дизайна of TypeScript, вы должны объявить все поля в классе с ключевым словом private и использовать property, чтобы заменить роль полей в общении с внешним миром.

4. Getter

Синтаксис Getter позволяет определить property, которое предоставляет доступ к его значению, но не может задать для него новое значение, если вы также не определили Setter для этого свойства.
Синтаксис:
get property_name(): data_type {
     // code ...
     return a_value;
}
// Or:
[private, protected, public] get property_name(): data_type {
     // code ...
     return a_value;
}
Например: Класс Employee ниже разрешает доступ к значению свойства empId, но не позволяет изменять значение этого property.
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();
Вы можете использовать ключевое слово private, protected или public в определении Getter.
// Getter
protected get empId(): number { // Property - empId
  return this._empId;
}

5. Setter

Синтаксис Setter позволяет определить property, позволяя присвоить ему новое значение. Однако без Getter попытка доступа к этому свойству приведет к получению неопределенного значения.
Синтаксис:
set property_name(new_value: data_type) {
     // code ...
}
// Or:
[private, protected, public] set property_name(new_value: data_type) {
     // code ...
}
Например: У класса Staff есть Setter, но нет Getter для property salary. Если вы попытаетесь получить доступ к значению salary, компилятор не сообщит об ошибке, но значение получено - 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
Вы можете использовать ключевое слово private, protected или public в определенииSetter. Его назначение аналогично тому, которое используется с полями.
// Setter
public set salary(salary: number) {
    this._salary = salary;
}