CLASSES | TS
Tags: webdev, typescript, beginners, programming
Published: 2024-06-12 06:58:53

# TypeScript Classes

TypeScript adds types and visibility modifiers to JavaScript classes.

## Members: Types

The members of a class (properties & methods) are typed using type annotations, similar to variables.

```ts
class Person {
  name: string;
}

const person = new Person();
person.name = "Jane";
```

## Members: Visibility

Class members also be given special modifiers which affect visibility.

There are three main visibility modifiers in TypeScript.

- **public** - (default) allows access to the class member from anywhere
- **private** - only allows access to the class member from within the class
- **protected** - allows access to the class member from itself and any classes that inherit it, which is covered in the inheritance section below

```ts
class Person {
    private name: string;

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

const person = new Person('Jane');
console.log(person.getName());
// console.log(person.name);  person.name isn't accessible from outside the class since it's private

```

## Parameter Properties

TypeScript provides a convenient way to define class members in the constructor, by adding a visibility modifiers to the parameter.

```ts
class Person {
    public constructor(private name: string) {
        this.name = name;
    }
    getName(): string {
        return this.name;
    }
}

const person = new Person('Birusha');
console.log(person.getName());
// console.log(person.name); Property 'name' is private and only accessible within class 'Person'

```

## Readonly

Similar to arrays, the readonly keyword can prevent class members from being changed.

```ts
class Person {
    readonly name: string;
    public constructor(name: string) {
        this.name = name;
    }
    getName(): string {
        return this.name;
    }
}

const person = new Person('John');
console.log(person.getName());
// person.name = 'Jill'; // Cannot assign to 'name' because it is a read-only property.

```

## Inheritance: Implements

```ts
interface Shape {
    getArea: () => number;
}

class Rectangle implements Shape {
    public constructor (
        private readonly width: number,
        private readonly height: number
    ) {}

    getArea(): number {
        return this.width * this.height;
    }
}


const r = new Rectangle(4, 3);
console.log(r.getArea());

```

## Inheritance: Extends


```ts
interface Shape {
    getArea: () => number;
}


class Rectangle implements Shape {
    public constructor(
        private readonly width: number,
        private readonly height: number
    ) {}

    getArea(): number {
        return this.width * this.height;
    }
}


class Square extends Rectangle {
    public constructor(width: number){
        super(width, width);
    }

    // getArea function is inherited
}

const s = new Square(40);
console.log(s.getArea());

```

## Override

When a class extends another class, it can replace the members of the parent class with the same name.

Newer versions of TypeScript allow explicitly marking this with the **override** keyword.


```ts
interface Shape {
    getArea: () => number;
}


class Rectangle implements Shape {
    public constructor(
        public readonly width: number,
        private readonly heigth: number
    ) {}

    getArea(): number {
        return this.width * this.heigth;
    }

    public toString(): string {
        return `Rectangle[width=${this.width}, height=${this.heigth}]`;
    }
}


class Square extends Rectangle {
    public constructor(width: number) {
        super(width, width);
    }

    // get area function inherited here

    public override toString(): string {
        return `Square[width=${this.width}]`;
    }
}


const rectangle = new Rectangle(20, 4);
const square = new Square(30);
console.log(rectangle.toString());
console.log(square.toString());

```


## Abstract Classes

Classes can be written in a way that allows them to be used as a base class for other classes without having to implement all the members. This is done by using the **abstract** keyword. Members that are left unimplemented also use the abstract keyword. 

```ts
abstract class Polygon {
    public abstract getArea(): number;

    public toString(): string {
        return `Polygon[area=${this.getArea()}]`;
    }
}


class Rectangle extends Polygon {
    public constructor (
        private readonly width: number,
        private readonly heigth: number
    ) 
    {
        super();
    }

    public getArea(): number {
        return this.width * this.heigth;
    }
}

const r = new Rectangle(43, 34);
console.log(r.getArea());

```