Problem: the calculation changes
A client displays a price for a number of seats. The regular offer charges 100 units per seat; another offer caps the total at 300. The client should work with both rules.
is an interchangeable way of performing an operation while preserving a shared . In a supplied is often enough.
A small example
Save as strategy.ts and run node strategy.ts in a version supporting this TypeScript . Execution does not check types — also run your project's typecheck command.
type Price = (seats: number) => number;
function preview(price: Price, seats: number): number {
if (!Number.isSafeInteger(seats) || seats < 0 || seats > 1000) {
throw new RangeError("Invalid seat count");
}
return price(seats);
}
const regular: Price = seats => seats * 100;
const capped: Price = seats => Math.min(seats * 100, 300);
console.log(preview(regular, 4));
console.log(preview(capped, 4));The outputs are 400 and 300. Here prices are integer and currency is agreed outside the function. This is a small model of one rule, not a complete pricing system.
What changes and what stays shared?
preview checks the seat count and calls the supplied function. regular and capped implement two algorithms. The client does not inspect offer names to choose calculation branches itself.
Flow: 4 seats → shared → selected rule → 400 or 300.
-1 is rejected before calculation. The number type alone guarantees neither an integer nor a valid range.
When should you avoid the pattern?
One stable rule with no need for interchangeability can stay a plain function. Strategy should support a real change. Creating classes solely to use a pattern name adds more places to .
Your small attempt
Predict both prices for 2 seats. Then add a rule that subtracts 50 units from the total without permitting a negative result. Check zero seats and write a test detecting a result below zero.
Sources
CHECK YOUR INTUITION

