TYPESCRIPT / CHAPTER 09
Classes, structural contracts, and private state
IntermediateKeep 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.
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}));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