TypeScript Property Modifiers Tutorial

In this TypeScript tutorial we learn how to use the readonly modifier to disable property mutation and the optional modifier to mark a property as non-constructing.

How to use the readonly property modfier

In TypeScript, we have certain modifiers that we can apply to our properties.

For example, let’s say we have an id property that should never change.

Example:
class Employee {
  id: number
  name: string

  constructor(id: number, name: string) {
    this.id = id
    this.name = name
  }

  walk(): void {
    console.log("Walking...")
  }
}

let emp1 = new Employee(0, 'John')
console.log('ID:', emp1.id)

At the moment, we can go inside our walk() method method and change it.

Example:
class Employee {
  id: number
  name: string

  constructor(id: number, name: string) {
    this.id = id
    this.name = name
  }

  walk(): void {
    this.id = -1
    console.log("Walking...")
  }
}

let emp1 = new Employee(0, 'John')
console.log('ID:', emp1.id)

Similarly, we can go outside the class and modify it on the object.

Example:
class Employee {
  id: number
  name: string

  constructor(id: number, name: string) {
    this.id = id
    this.name = name
  }

  walk(): void {
    console.log("Walking...")
  }
}

let emp1 = new Employee(0, 'John')
emp1.id = -1
console.log('ID:', emp1.id)

This could lead to bugs or security issues in our application.

To solve this problem, we use the readonly modifier.

To use it, we add the modifier in front of the property we want to restrict.

Syntax:
class ClassName {
  readonly property: type
}

To demonstrate, let’s change the id property in our example.

Example:
class Employee {
  readonly id: number
  name: string

  constructor(id: number, name: string) {
    this.id = id
    this.name = name
  }

  walk(): void {
    console.log("Walking...")
  }
}

let emp1 = new Employee(0, 'John')
emp1.id = -1
console.log('ID:', emp1.id)

Now the property can only be set in the constructor and if we try to modify it somewhere else, it’ll raise an error.

So we’ll remove the line below he object instantiation that tries to modify the property.

Example:
class Employee {
  readonly id: number
  name: string

  constructor(id: number, name: string) {
    this.id = id
    this.name = name
  }

  walk(): void {
    console.log("Walking...")
  }
}

let emp1 = new Employee(0, 'John')
console.log('ID:', emp1.id)

How to use the optional property modifier

Another useful modifier is the optional modifier.

Let’s say we add a nickname property to the class. For the user it’ll be completely optional, they can choose if they want it or not, so we don’t want to set it in the constructor.

Example:
class Employee {
  readonly id: number
  name: string
  nickname: string

  constructor(id: number, name: string) {
    this.id = id
    this.name = name
  }

  walk(): void {
    console.log("Walking...")
  }
}

let emp1 = new Employee(0, 'John')
console.log('ID:', emp1.id)

To mark a property as optional, we just add a ? (question mark) after its name.

Syntax:
class ClassName {
  property?: type
}

To demonstrate, let’s mark our nickname property as optional. And that will also clear the error that we need to construct it.

Example:
class Employee {
  readonly id: number
  name: string
  nickname?: string

  constructor(id: number, name: string) {
    this.id = id
    this.name = name
  }

  walk(): void {
    console.log("Walking...")
  }
}

let emp1 = new Employee(0, 'John')
console.log('ID:', emp1.id)

We’ll talk about how to safely change property values a little later on, for now, let’s move on to accesss modifiers.

Summary: Points to remember

  • If we don’t want a property to be mutable, we mark it with the readonly modifier in front of the name.
  • If we want a property to be optional, where we don’t need to construct it, we mark it with a ? (question mark) after the name.