TypeScript - Readonly Properties: A Beginner's Guide

Hello there, future coding superstar! Today, we're going to dive into the wonderful world of TypeScript and explore one of its powerful features: readonly properties. Don't worry if you're new to programming; I'll be your friendly guide on this exciting journey. So, grab your favorite beverage, get comfy, and let's embark on this TypeScript adventure together!

TypeScript - Readonly Properties

What Are Readonly Properties?

Before we jump into the nitty-gritty, let's understand what readonly properties are. Imagine you have a precious family heirloom - maybe a beautiful antique watch. You can look at it, admire it, but you can't change it. That's exactly what readonly properties are in TypeScript - values that you can see and use, but can't modify once they're set.

Syntax

Let's start with the basics. How do we declare a readonly property? It's as simple as adding the readonly keyword before the property name. Here's a basic example:

class Heirloom {
    readonly name: string;

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

const familyWatch = new Heirloom("Grandfather's Watch");
console.log(familyWatch.name); // Output: Grandfather's Watch
// familyWatch.name = "New Watch"; // Error! Can't modify a readonly property

In this example, once we set the name in the constructor, we can't change it later. It's like sealing the name of our family heirloom in time!

The readonly Properties with Interface

Interfaces in TypeScript are like blueprints for objects. We can use readonly properties in interfaces too. Let's see how:

interface ReadonlyPerson {
    readonly name: string;
    readonly age: number;
}

const person: ReadonlyPerson = {
    name: "Alice",
    age: 30
};

console.log(person.name); // Output: Alice
// person.age = 31; // Error! Can't modify a readonly property

Here, we've created a ReadonlyPerson interface where both name and age are readonly. Once we create an object based on this interface, we can't change these properties. It's like creating an ID card - once printed, you can't just scratch out the age and write a new one!

The readonly Properties with Classes

Classes are like blueprints for creating objects with both data and behavior. Let's see how readonly properties work in classes:

class Book {
    readonly title: string;
    readonly author: string;
    private _pageCount: number;

    constructor(title: string, author: string, pageCount: number) {
        this.title = title;
        this.author = author;
        this._pageCount = pageCount;
    }

    get pageCount(): number {
        return this._pageCount;
    }

    addPages(pages: number) {
        this._pageCount += pages;
    }
}

const myBook = new Book("TypeScript 101", "Jane Doe", 200);
console.log(myBook.title); // Output: TypeScript 101
myBook.addPages(50);
console.log(myBook.pageCount); // Output: 250
// myBook.title = "JavaScript 101"; // Error! Can't modify a readonly property

In this example, title and author are readonly, but we can still modify pageCount through a method. It's like a book - once printed, you can't change the title or author, but you can add pages (maybe in a revised edition).

The readonly Properties with Type Aliases

Type aliases are like nicknames for types. We can use readonly properties with them too:

type ReadonlyPoint = {
    readonly x: number;
    readonly y: number;
};

const point: ReadonlyPoint = { x: 10, y: 20 };
console.log(point.x, point.y); // Output: 10 20
// point.x = 30; // Error! Can't modify a readonly property

Here, we've created a ReadonlyPoint type where both x and y are readonly. It's like setting coordinates on a map - once placed, you can't move the point!

Const vs. readonly Properties

Now, you might be wondering, "What's the difference between const and readonly?" Great question! Let's break it down:

const PI = 3.14159;
// PI = 3.14; // Error! Can't reassign a const variable

class Circle {
    readonly radius: number;

    constructor(radius: number) {
        this.radius = radius;
    }
}

const circle = new Circle(5);
// circle.radius = 10; // Error! Can't modify a readonly property

const is used for variables that can't be reassigned. readonly is used for properties that can't be changed after initialization. Think of const as a promise not to change the container, while readonly is a promise not to change the contents.

When to Use Readonly

So, when should you use readonly properties? Here are some common scenarios:

  1. When you have values that shouldn't change after initialization.
  2. For configuration objects that should remain constant.
  3. To prevent accidental modifications in large codebases.
  4. When working with immutable data structures.

Here's a table summarizing the methods we've discussed:

Method Description Example
With Interfaces Define readonly properties in object blueprints interface ReadonlyPerson { readonly name: string; }
In Classes Create class properties that can't be modified after initialization class Book { readonly title: string; }
With Type Aliases Define readonly properties in custom types type ReadonlyPoint = { readonly x: number; readonly y: number; }
Const vs Readonly Use const for variables, readonly for properties const PI = 3.14; class Circle { readonly radius: number; }

Remember, using readonly properties is like setting rules for your future self and other developers. It helps prevent mistakes and makes your code more predictable and maintainable.

And there you have it, my dear students! We've journeyed through the land of readonly properties in TypeScript. I hope this guide has illuminated the path for you. Remember, practice makes perfect, so don't be afraid to experiment with these concepts in your own projects. Happy coding, and may your readonly properties always stay true to their values!

Credits: Image by storyset