Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding private methods in typescript

Tags:

typescript

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?

like image 673
GGizmos Avatar asked Mar 21 '26 10:03

GGizmos


1 Answers

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 protected modifier acts much like the private modifier with the exception that members declared protected can 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

like image 88
cherryblossom Avatar answered Mar 24 '26 23:03

cherryblossom



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!