o7planning

TypeScript Properties Tutorial with Examples

  1. What is Field?
  2. Private, Protected & Public Fields
  3. What is Property?
  4. Getter
  5. Setter

1. What is Field?

In this lesson, we will discuss properties in TypeScript. But before we get into the main content, we need to clarify the concept of fields.
A field is a variable declared directly in a class.
See the article about constructors to understand how TypeScript assigns values to fields:
In the TypeScript language, if you can access a field, you can get its value and set a new value for it. For example:
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 older than 3.8
TypeScript older than 3.8 not yet provides the private, protected and public keywords. To have a private field, programmers name it starting with a pound character ( # ). These fields can only be accessed within the class that defined them.
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+
Starting from version 3.8, TypeScript supports private, protected and public keywords in a field declaration.
class Class_Name  {
   private field1: string;
   protected field2 : string;
   public field3 : string;
   field4 : string; // Default =  public
}
Modifier
Description
private
The field can only be accessed within the class that defines it.
protected
The field can be accessed in the class that defines it, or in subclasses.
public
The field can be accessed anywhere.
In the example below, a field is declared with the private keyword, which cannot be accessed outside the class that defined it.
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. What is Property?

Basically, once you have access to a field somewhere, you can retrieve its value and assign a new value to it.
Property is a concept similar to a field, but it has more special features. Property is divided into 3 types:
  • Read-only Property: Allows access to its value, but does not allow to set a new value for it.
  • Write-only Property: Allows to set a new value for it. However, trying to access this property will get undefined value.
  • Read/Write Property: Allows access to the current value and sets a new value for it.
According to the TypeScript design idea, you should declare all fields in the class with the private keyword, and use properties to replace the role of fields in communicating with the outside world.

4. Getter

The Getter syntax allows you to define a property that allows access to its value, but cannot set a new value for it unless you also define a Setter for this property.
Syntax:
get property_name(): data_type {
     // code ...
     return a_value;
}
// Or:
[private, protected, public] get property_name(): data_type {
     // code ...
     return a_value;
}
Example: The Employee class below allows access to the value of the empId property, but does not allow to change the value of this 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();
You can use the private, protected or public keyword in the Getter definition.
// Getter
protected get empId(): number { // Property - empId
  return this._empId;
}

5. Setter

The Setter syntax allows you to define a property, allowing you to assign a new value to it. However, without the Getter, trying to access this property will get underfined value.
Syntax:
set property_name(new_value: data_type) {
     // code ...
}
// Or:
[private, protected, public] set property_name(new_value: data_type) {
     // code ...
}
Example: Staff class has a Setter but no Getter for the salary property. If you try to access the value of salary, the compiler will not report an error, but the value is 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
You can use the private, protected or public keyword in the Setter definition. Its meaning is similar to that used with fields.
// Setter
public set salary(salary: number) {
    this._salary = salary;
}