Read-Only Fields

Some values shouldn't change once an object exists: a hero's name, the number of a quest, an id in a save file. In lesson 4, you marked such properties readonly, and fields of a class work the same way:

class Hero {
    readonly id: number;
    readonly name: string;
    level: number = 1;

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

    rename(newName: string): void {
        this.name = newName;
    }
}

const kira = new Hero(1, "Kira");
kira.name = "Kiraa";

TypeScript reports:

main.ts(12,14): error TS2540: Cannot assign to 'name' because it is a read-only property.
main.ts(17,6): error TS2540: Cannot assign to 'name' because it is a read-only property.

A readonly field gets its value either as its initial value or in the constructor, and those are the only places where it can be assigned. After that, nobody can change it: not the code outside the class, and not even the class's own methods, like rename above. Reading is allowed everywhere: kira.name is fine.

readonly or private? They protect different things:

  • private is about who can use the field: only the class can read it and change it.
  • readonly is about when it can change: only while the object is being created. Anyone can read it.

You can combine them: private readonly secret: string; is a field that only the class can read, and that never changes. And compared with const: const is for variables, readonly for fields and properties.

Like private, readonly exists only for TypeScript; the JavaScript that runs has an ordinary property. But since TypeScript checks the whole program before it runs, no line of your program can change the field.

A read-only field catches more than deliberate changes. Remember the classic mistake from the JavaScript course, = instead of === in a condition? The program in the editor has it.

Instructions

Run the program: it prints Bruno is here!, and Kira is suddenly called Bruno. Make the fields id and name read-only. TypeScript then reports the line with the mistake; fix it, so that it compares the name instead of assigning it. Kira stays Kira:

Hero { id: 1, name: "Kira", level: 2 }

Add a third read-only field after name: heroClass of type HeroClass (the type is at the top of the program). The constructor gets it as a third parameter. Create Kira as a ranger, new Hero(1, "Kira", "ranger"). The program then prints:

Hero { id: 1, name: "Kira", heroClass: "ranger", level: 2 }

Start programming for free

By signing up, you agree to the Terms of Service and Privacy Policy.

Or sign up with:

5/9