What It Is
The Template Method pattern fixes the skeleton of an algorithm — the steps and their order — while letting the individual steps vary. The recipe is written once; each variant fills in its own steps.
TypeScript writes this with an abstract class. The skeleton is a normal method on the base class; the varying steps are abstract methods with no body, so every subclass has to provide them and the base class cannot be created on its own.
Example: One Recipe, Two Drinks
make() owns the order: boil, brew, pour, extras. Tea and Coffee only answer how to brew and what to add — they cannot reorder or skip steps.
The skeleton stays fixed
Both drinks print the same four steps in the same order, because the order lives in one method: boil water, the brew line, pour into cup, the extras line. A new drink implements two methods and inherits the whole discipline.
Output: TypeScript file and captured output
abstract class Drink {
private label: string
constructor(label: string) {
this.label = label
}
// The fixed skeleton: the order of the steps lives here, once.
make(): void {
console.log("--", this.label)
console.log("boil water")
console.log(this.brew())
console.log("pour into cup")
console.log(this.extras())
}
// The variable steps: every drink must fill these in.
protected abstract brew(): string
protected abstract extras(): string
}
class Tea extends Drink {
constructor() {
super("tea")
}
protected brew(): string {
return "steep the tea leaves"
}
protected extras(): string {
return "add lemon"
}
}
class Coffee extends Drink {
constructor() {
super("coffee")
}
protected brew(): string {
return "run water through the coffee"
}
protected extras(): string {
return "add milk"
}
}
new Tea().make()
new Coffee().make()
When to Use It
Use it when several procedures share the same fixed sequence with different details — report generation, import pipelines, test setups.
Skip it when the variants also need different orders — forcing them under one skeleton bends the pattern until it breaks. And with one variant, the skeleton is just a function.
Pros and Cons
Pros: the sequence is enforced in one place; variants cannot forget or shuffle steps; shared steps are written once; a forgotten step is a compile error, not a surprise at run time.
Cons: rigid by design — a variant that needs “almost the same, but...” fights the skeleton; too many hook methods make the recipe hard to follow.