WHAT'S NEW
TypeScript · Lesson 08 of 11

Building with Classes

Create reusable blueprints for real-world objects. Combine data and behavior, control access to properties, and extend classes to build more capable programs.

Constructors Methods Public & Private Inheritance
● ● ●   classes.ts
class Developer {
  name: string;
  level: number;

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

  greet() {
    return "Hello, " + this.name;
  }
}

const moe = new Developer("Moe");
CONSOLE OUTPUT
> Ready to run…
01 / What Is a Class?

Create Blueprints for Objects

In the previous lesson, you learned that an interface describes the structure an object should follow. A class goes further: it provides the actual code for creating objects, including their properties and methods.

Imagine you’re building a website that tracks developer profiles. Instead of writing every profile object from scratch, you can define a class and create as many developers as you need.

first-class.ts
class Developer {
  name: string = "Moe";
  level: number = 8;
}

const moe = new Developer();

console.log(moe.name);
console.log(moe.level);
Console Output:
Moe 8

The class keyword creates the blueprint. The new keyword creates an individual object, called an instance, from that blueprint.

Remember: A class is the blueprint; an instance is an object created from it.
02 / Constructors

Customize Objects When You Create Them

A constructor runs automatically when you create an instance using new. It lets you provide different starting values for each object.

constructor.ts
class Developer {
  name: string;
  level: number;

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

const moe = new Developer("Moe", 8);
const jordan = new Developer("Jordan", 5);

console.log(moe.name);
console.log(jordan.level);
Console Output:
Moe 5

Each instance gets its own property values. The keyword this refers to the current instance, so this.name means the name property of that particular object.

03 / Class Methods

Give Your Objects Something to Do

Properties describe an object. Methods define actions that the object can perform.

methods.ts
class Developer {
  constructor(public name: string) {}

  greet(): void {
    console.log("Hello from " + this.name);
  }
}

const moe = new Developer("Moe");
moe.greet();
Console Output:
Hello from Moe

Notice public name: string in the constructor. This is a TypeScript parameter property: it declares and initializes the property without needing a separate assignment.

04 / Public and Private

Control Access to Properties

TypeScript provides access modifiers that describe where class members can be accessed.

access-modifiers.ts
class Developer {
  public name: string;
  private points: number;

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

  addPoints(amount: number): void {
    this.points += amount;
  }

  showPoints(): void {
    console.log(this.points);
  }
}

const moe = new Developer("Moe");
moe.addPoints(25);
moe.showPoints();

// TypeScript error:
// console.log(moe.points);
Console Output:
25

public members can be accessed from outside the class. private members can only be accessed from within the declaring class.

Important: TypeScript’s private modifier is enforced by the type checker. JavaScript’s #privateField syntax provides runtime-enforced privacy.
05 / Readonly Properties

Protect Values After Initialization

A readonly property can be assigned when declared or inside the constructor, but cannot be reassigned afterward through normal TypeScript code.

readonly.ts
class Developer {
  readonly id: number;
  name: string;

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

const moe = new Developer(108, "Moe");
moe.name = "Moe M.";

// TypeScript error:
// moe.id = 200;

Readonly properties are useful for identifiers and other values that should stay consistent after an object is created.

06 / Getters and Setters

Control How Values Are Read and Updated

Getters and setters let a class expose a property-like interface while controlling how a value is accessed or changed.

getters-setters.ts
class Developer {
  private _level: number = 1;

  get level(): number {
    return this._level;
  }

  set level(value: number) {
    if (value > 0) {
      this._level = value;
    }
  }
}

const moe = new Developer();
moe.level = 8;

console.log(moe.level);
Console Output:
8

The setter checks that the new level is positive before saving it. The getter returns the current value.

07 / Inheritance

Build New Classes from Existing Ones

Inheritance lets one class reuse and extend the behavior of another. Use extends to create a subclass.

inheritance.ts
class Person {
  constructor(public name: string) {}

  greet(): void {
    console.log("Hello, I'm " + this.name);
  }
}

class Developer extends Person {
  constructor(
    name: string,
    public language: string
  ) {
    super(name);
  }
}

const moe = new Developer("Moe", "TypeScript");
moe.greet();
console.log(moe.language);
Console Output:
Hello, I’m Moe TypeScript

The Developer class inherits name and greet() from Person. The super(name) call runs the parent class’s constructor.

08 / Method Overriding

Customize Inherited Behavior

A subclass can provide its own implementation of a method inherited from its parent class. TypeScript’s override keyword makes that intention explicit.

override.ts
class Person {
  greet(): void {
    console.log("Hello!");
  }
}

class Developer extends Person {
  override greet(): void {
    console.log("Hello from a developer!");
  }
}

const moe = new Developer();
moe.greet();
Console Output:
Hello from a developer!

The subclass replaces the inherited implementation with its own behavior. The method still needs a compatible signature.

09 / Implementing Interfaces

Connect Classes to Your Type Contracts

Classes and interfaces work together. A class can use implements to promise that it provides the properties and methods required by an interface.

implements.ts
interface Profile {
  name: string;
  introduce(): void;
}

class Developer implements Profile {
  constructor(public name: string) {}

  introduce(): void {
    console.log("Developer: " + this.name);
  }
}

const moe = new Developer("Moe");
moe.introduce();
Console Output:
Developer: Moe

The interface checks the class’s public structure, while the class provides the working implementation.

Think of it this way: An interface defines what an object must provide; a class can define how those features actually work.
10 / Putting It Together

Build a Developer Progress Tracker

Let’s create a developer class that stores a name, tracks a level, and allows progress through a method.

progress-tracker.ts
class Developer {
  constructor(
    public name: string,
    private level: number
  ) {}

  levelUp(): void {
    this.level++;
  }

  showProfile(): void {
    console.log("Developer: " + this.name);
    console.log("Level: " + this.level);
  }
}

const moe = new Developer("Moe", 7);
moe.levelUp();
moe.showProfile();
Console Output:
Developer: Moe Level: 8

With a single class, you now have a reusable way to create developer profiles and update their progress.

🚀 mC0de Challenge

Create Your Developer Progress Tracker

Build a reusable class that tracks a developer’s learning journey.

Your Mission

  1. Create a class named Developer.
  2. Use a constructor to accept a developer’s name and starting level.
  3. Make the name public and the level private.
  4. Add a levelUp() method that increases the level by one.
  5. Add a showProfile() method that prints the developer’s name and level.
  6. Create a developer named Moe, call levelUp(), and display the updated profile.
  7. Experiment with changing the level directly from outside the class and examine the TypeScript error.
Extra challenge: Add a readonly id property and a getter that returns the current level.
💻 Interactive TypeScript Sandbox

Build Your Developer Class!

Edit the class, create developer instances, and run the program. TypeScript checks your code before the compiled JavaScript runs.

Console Output
Lesson 08 Recap

What You’ve Learned

You’re Building Reusable Programs!

You can now:

  • Define classes and create instances with new.
  • Initialize properties using constructors.
  • Create methods that work with instance data.
  • Use public, private, and readonly.
  • Control property access using getters and setters.
  • Extend classes using inheritance.
  • Override inherited methods.
  • Implement interfaces with classes.

Next up: Generics — learn how to write reusable TypeScript code that works with multiple types while preserving type safety!

Your Learning Journey

0 / 11 Completed

You’re eight lessons into your TypeScript journey. Keep building!

🎉

You’re Mastering TypeScript!

You’ve learned how to create classes, initialize objects with constructors, define methods, control property access, and extend classes. You’re now building reusable code with object-oriented programming!

PIX0
</> {} JS 01
0101 </> CSS JS HTML PIX0 const {} 1010 async mC0de function return 0101 <div> 1010 PIX0 CSS JS HTML const {} 0101 mC0de
PIX0 // WORLD OF CODE
PIX0 IS PREPARING SOMETHING AWESOME FOR YOU 0%