๐ŸŽ“ A1Learner
๐Ÿ”
0 of 42 lessons completed

TypeScript Class Modifiers in Depth

Parameter properties declare class fields inside the constructor signature. This lesson also deepens protected access, readonly fields, and hash-private fields.

Parameter properties declare fields in the constructor

Each parameter carries a modifier, so each one is also a field. The describe method reads all three fields.

class Ticket {
  constructor(
    private readonly id: number,
    public title: string,
    protected priority: number
  ) {}
  describe(): string {
    return `#${this.id} ${this.title} (p${this.priority})`;
  }
}
const ticket = new Ticket(7, "Fix login", 2);
console.log(ticket.describe());
console.log(ticket.title);

A protected member works inside a subclass

The subclass reads and changes the protected balance through inherited code. No outside code touches the field directly.

class Account {
  protected balance = 100;
  protected fee(amount: number): void {
    this.balance -= amount;
  }
}
class Savings extends Account {
  chargeFee(): void {
    this.fee(5);
  }
  report(): number {
    return this.balance;
  }
}
const sav = new Savings();
sav.chargeFee();
console.log(sav.report());

A protected member is refused from outside

The same field is reachable inside the class family only. Reading it through an instance from outside code fails.

class Account {
  protected balance = 100;
  showBalance(): number {
    return this.balance;
  }
}
const acc = new Account();
console.log(acc.balance);

A hash-private field counts inside the class

The field name starts with #, so JavaScript itself hides it. Only methods of the class can reach it.

class Clicker {
  #count = 0;
  bump(): void {
    this.#count++;
  }
  value(): number {
    return this.#count;
  }
}
const clicker = new Clicker();
clicker.bump();
clicker.bump();
clicker.bump();
console.log(clicker.value());

Hash-private access and readonly writes are refused

Two refusals appear here. The first line reaches for the # field from outside, and the second assigns to a readonly field after construction.

class Vault {
  #code = 4321;
  readonly limit: number;
  constructor(limit: number) {
    this.limit = limit;
  }
  reveal(): number {
    return this.#code;
  }
}
const vault = new Vault(3);
console.log(vault.#code);
vault.limit = 9;

Example

class Order {
  #items = 0;
  constructor(
    public readonly code: string,
    protected discount = 0
  ) {}
  addItem(): void {
    this.#items++;
  }
  summary(): string {
    return `${this.code}: ${this.#items} items, discount ${this.discount}`;
  }
}
class MemberOrder extends Order {
  applyDiscount(): void {
    this.discount = 10;
  }
}
const order = new MemberOrder("ORD-1");
order.addItem();
order.addItem();
order.applyDiscount();
console.log(order.summary());
console.log(order.code);

Key points

  • A parameter property is a constructor parameter with an access modifier or readonly.
  • The modifier turns the parameter into a field, with no separate declaration or assignment.
  • A protected member is reachable inside the class and its subclasses.
  • A protected member is refused from code outside the class family.
  • A field written with a leading # is private by JavaScript itself, not only by the checker.
  • A readonly field accepts its value during construction and refuses later assignment.

In this example, parameter properties declare the code and discount fields in one signature. The subclass sets the protected discount, and the hash-private item count stays inside the base class.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท TypeScript Playground

Exercise

Which constructor parameter declares a class field?