First things first: a word of caution – do this only if you absolutely have to. TypeScript has these checks for a reason, and probably in 99% of the cases you should respect and abide these restrictions. But if your scenario falls within the 1% where you must in a subclass override a private method of a superclass – this post shows a way to do this.
Let’s say we have a class that defines a generic starship, and what happens to it when it’s hit by a weapon:
type Hit = 'phaser' | 'antimatter spread' | 'photon torpedo'
class Starship {
private totalDamage: number;
constructor(private shipName: string) {
this.totalDamage = 0;
}
private addDamage(damage: number) {
this.totalDamage += damage;
}
public isHitBy(hit: Hit) {
console.log(`${this.shipName} is hit by ${hit}!`)
switch(hit) {
case 'phaser':
this.addDamage(100);
break;
case 'antimatter spread':
this.addDamage(300);
break;
case 'photon torpedo':
this.addDamage(500);
break
}
}
}
You can create your own class of starship based on this generic class, then build a ship of the new class, and simulate it being hit by a weapon:
class Galaxy extends Starship {
constructor(name: string) {
super(name);
}
}
const enterprise = new Galaxy('Enterprise');
enterprise.isHitBy('photon torpedo');
Output:
"Enterprise is hit by photon torpedo!"
This is fine, but as you’ve seen the base class has a secret feature to calculate damage inflicted by the weapon. It is secret, because it’s defined by a private method, and is not exposed to derived classes. But, like Kirk in Kobayashi Maru, you want to break the rules, and have this forbidden knowledge. Continue reading →