TYPESCRIPT / CHAPTER 09

Classes, structural contracts, and private state

Intermediate

Keep public behavior separate from runtime representation.

By the end of this chapter

  • Implement a small interface
  • Understand structural compatibility
  • Avoid treating TypeScript private as runtime validation

The idea

An interface describes capabilities, and a class can implement that shape. Code depending on the interface can accept other compatible implementations without requiring a shared superclass. The implements clause checks the class; it does not change the inferred types of every member body or construct missing methods automatically.

Public structure usually determines compatibility, but private and protected members introduce origin-related restrictions for class compatibility. TypeScript’s private keyword is primarily a checker restriction and is distinct from JavaScript #private fields with runtime enforcement. Neither feature validates an arbitrary external object. Keep mutation behind methods that enforce domain rules, and expose only the observations clients actually need.

TypeScript example
interface Reading { value(): number; }
class Fixed implements Reading {
  constructor(private amount: number) {}
  value(): number { return this.amount; }
}
function doubled(reading: Reading): number { return reading.value() * 2; }
console.log(doubled(new Fixed(6)));
console.log(doubled({value: () => 4}));
Result
12
8

Both the class instance and the object literal satisfy the required public behavior.

Try it yourself

Define a pricing interface and two independent implementations that enforce nonnegative prices at construction.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

Which value satisfies interface Named { name: string } structurally?