Add types to your classes

INPUT · Slides

Guard things with private and readonly

01 / 05

Anyone outside can change it

With nothing written on it, a field can be read and written freely from outside. Handy, but nothing stops an odd value going in.

The balance below can be made -500 from outside. As far as TypeScript is concerned you only "put a number where a number goes", so it goes through.

class Savings {  balance: number;  constructor(balance: number) {    this.balance = balance;  }}const c = new Savings(1000);c.balance = -500;console.log(c.balance);

Result

-500

02 / 05

Add private and outside cannot touch it

Write private in front of the field name and it can only be read or written from inside that class. Try to touch it from outside and you are stopped before anything runs.

What you get is "Property 'balance' is private and only accessible within class 'Savings'".

class Savings {  private balance: number;  constructor(balance: number) {    this.balance = balance;  }}const c = new Savings(1000);c.balance = -500;

Result

Type error: Property 'balance' is private and only accessible within class 'Savings'.

03 / 05

From inside, nothing has changed

private only bites from outside. From a method inside the class you read and write through this. exactly as before.

So you provide, as methods, only the operations you want to expose. That way a rule like "never go negative" can be kept inside the class.

class Savings {  private balance: number;  constructor(balance: number) {    this.balance = balance;  }  deposit(amount: number): void {    this.balance = this.balance + amount;  }  look(): number {    return this.balance;  }}const c = new Savings(1000);c.deposit(500);console.log(c.look());

Result

1500

04 / 05

readonly is only while you make it

A field with readonly cannot be changed once the constructor has filled it. Put it on things you do not want moving later, like a membership number or a date of birth.

Reading it from outside is fine. Only rewriting is forbidden.

class Member {  readonly id: number;  constructor(id: number) {    this.id = id;  }}const k = new Member(7);k.id = 9;

Result

Type error: Cannot assign to 'id' because it is a read-only property.

05 / 05

The two are after different things

  • private … decides where from it can be touched (only inside the class)
  • readonly … decides until when it can be changed (only while it is made)

Using both in one class is fine. When in doubt, go field by field and ask "does this need to be visible outside?" and "does this need to change later?". Right, have a go.

class Member {  readonly id: number;  private points: number;  constructor(id: number) {    this.id = id;    this.points = 0;  }  earn(n: number): void {    this.points = this.points + n;  }  look(): number {    return this.points;  }}const k = new Member(7);k.earn(30);console.log(k.id);console.log(k.look());

Result

7
30