Classes and OOP

The Security Breach That Never Happened

It was code review day. A junior developer had submitted a PR for our payment processing service.

// payment-service.js - Old JavaScript code
class PaymentProcessor {
  constructor(apiKey, secretKey) {
    this.apiKey = apiKey;
    this.secretKey = secretKey;
  }
  
  processPayment(amount, cardToken) {
    // All properties are public!
    const signature = this.generateSignature(amount, cardToken);
    return fetch('/api/payments', {
      headers: {
        'X-API-Key': this.apiKey,
        'X-Signature': signature
      }
    });
  }
  
  generateSignature(amount, cardToken) {
    return crypto.createHmac('sha256', this.secretKey)
      .update(`${amount}:${cardToken}`)
      .digest('hex');
  }
}

// Later in the code...
const processor = new PaymentProcessor(API_KEY, SECRET_KEY);

// Someone logged the entire object for debugging
console.log('Processor:', processor);
// OUTPUT: { apiKey: '...', secretKey: '...' }  // SECRET EXPOSED!

The secretKey was accessible. It got logged. It almost made it to our logging service. If this had gone to production, our payment credentials would have been in plain text logs.

I caught it during code review. We migrated to TypeScript:

Result: Private credentials stayed private. The compiler prevented accidental exposure.

This article covers TypeScript's class features that turn design intentions into compiler-enforced guarantees.


Basic Class Syntax

Classes in TypeScript build on JavaScript with type annotations.

Simple Class

Property Initialization


Access Modifiers

Control property and method visibility.

public (default)

private

protected

Real-World Example


Parameter Properties

Shorthand for constructor parameters that become class properties.

Before Parameter Properties

With Parameter Properties

Mixed Access Modifiers


Readonly Properties

Properties that cannot be reassigned after initialization.

Basic Readonly

Readonly Parameter Properties


Getters and Setters

Control property access with methods.

Basic Accessor

Computed Properties

Validation in Setters


Static Members

Properties and methods that belong to the class itself.

Static Properties

Static Factory Methods


Abstract Classes

Base classes that cannot be instantiated directly.

Basic Abstract Class


Implementing Interfaces

Classes can implement one or more interfaces.

Single Interface

Multiple Interfaces


Real-World Patterns

1. Repository Pattern

2. Service Layer Pattern

3. Builder Pattern


Your Challenge

Build a type-safe shopping cart system:


Key Takeaways

  1. Access modifiers - public, private, protected control visibility

  2. Parameter properties - shorthand for constructor parameters

  3. Readonly - prevent reassignment after initialization

  4. Getters/setters - control property access

  5. Static members - belong to class, not instances

  6. Abstract classes - define contracts for subclasses

  7. Implements - classes can implement interfaces

  8. Encapsulation - hide implementation details


What I Learned

The payment security incident taught me: access modifiers aren't documentation - they're guarantees.

In JavaScript:

Everything is public. Logging objects exposes secrets. Debugging leaks credentials. One console.log away from disaster.

In TypeScript:

The compiler prevents accidental exposure. Private means actually private. Design intentions become enforced constraints.

Before TypeScript, we had conventions:

  • "Don't access _privateField"

  • "Use getters/setters"

  • "Read the documentation"

After TypeScript, we have guarantees:

  • Private fields cannot be accessed outside the class

  • Readonly fields cannot be reassigned

  • Abstract methods must be implemented

Access modifiers turn code review findings into compile-time errors.

The security vulnerability was caught in review. With TypeScript, it would have been caught instantly during development.

Make invalid access impossible. Let the compiler guard your secrets.


Next: Enums

In the next article, we'll explore TypeScript enums. You'll learn how const enums helped reduce our bundle size by 40KB while improving type safety.

Last updated