Noting that this version with public method message() compiles and greet() works as expected,
class Foo {
public greet() {
console.log(`Hello, ${this.getMessage()}`);
}
getMessage() : string {
return "I am Foo"
}
}
class Goo extends Foo {
getMessage() : string {
return "I am Goo";
}
}
but with getMessage() marked private, class Goo no longer compiles:
class Foo {
public greet() {
console.log(`Hello, ${this.getMessage()}`);
}
private getMessage() : string {
return "I am Foo"
}
}
class Goo extends Foo {
private getMessage() : string {
return "I am Goo";
}
}
I often use private methods to break up larger methods by abstracting out chunks of low level code to improve readability as many books on the subject recommend, and I make them private because they are not intended to be called by consumers of the class, but for some reason typescript is working against me when one of these lower level methods needs to be modified for certain subclasses of my base class.
Practically speaking is there some other way to do this, aside from having to implement the public method in the extended class as well, or exposing the "dirty laundry" of the support method by including it the public interface of the base and child classes?
Also I'm wondering just as a matter of interest what is the motivation of the typescript authors for this seemingly arbitrary rule that public methods can be overriden but private methods can't?
As bryan60 said, use the protected modifier:
class Foo {
public greet() {
console.log(`Hello, ${this.getMessage()}`);
}
protected getMessage(): string {
return "I am Foo";
}
}
class Goo extends Foo {
protected getMessage(): string {
return "I am Goo";
}
}
const goo = new Goo();
goo.greet(); // Hello, I am Goo
From the handbook:
The
protectedmodifier acts much like theprivatemodifier with the exception that members declaredprotectedcan also be accessed within deriving classes.
For example:
// Property 'getMessage' is protected and only accessible within class 'Goo'
// and its subclasses.
goo.getMessage();
class Hoo extends Goo {
public getMessage(): string {
return "I am Hoo";
}
public tryToGetGoosMessage(goo: Goo): string {
// Property 'getMessage' is protected and only accessible through an
// instance of class 'Hoo'.
return goo.getMessage();
}
public doOtherHoosHoo(hoo: Hoo) {
// ok, this is inside Hoo
hoo.hoo();
}
protected hoo() {}
}
const hoo = new Hoo();
// ok, getMessage is public in Hoo
hoo.getMessage();
// Class 'Joo' incorrectly extends base class 'Hoo'.
// Property 'getMessage' is protected in type 'Joo' but public in type 'Hoo'.
class Joo extends Hoo {
protected getMessage(): string {
return "I am Joo";
}
}
Playground link
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With