Mathias Dewelde
Mathias Dewelde

Reputation: 705

Accessing protected method from other instance with same parent class in typescript

I'm porting code from PHP to NodeJs (Typescript). And i came across the following PHP code (simplified)           

<?php
class A {
    protected function protectedData() {
        return 'accessible';
    }
}
class B extends A {
    public function extractTest($anInstanceOfA) {
        return $anInstanceOfA->protectedData();
    }
}
$instanceA = new A();
$instanceB = new B();
echo $instanceB->extractTest($instanceA);

Running it in a sandbox results in an echo "accessible".

I wrote the same code in Typescript, but that does not seem to work...

class A {
  protected protectedData(): string {
    return 'accessible';
  }
}

class B extends A {
  public extractTest(anInstanceOfA: A): string {
    return anInstanceOfA.protectedData();
  }
}

const instanceA = new A();
const instanceB = new B();


console.log(instanceB.extractTest(instanceA));

           

Error: Property 'protectedData' is protected and only accessible through an instance of class 'B'.(2446)  

Is there a way to achieve this in Typescript or is there a big difference between protected methods in PHP and Typescript?

Upvotes: 3

Views: 6081

Answers (1)

ford04
ford04

Reputation: 74510

From the docs:

The protected modifier acts much like the private modifier with the exception that members declared protected can also be accessed within deriving classes.

In above case, you use protectedData as method from a function parameter anInstanceOfA, that happens to be of base type A. But you don't access protectedData within deriving class B by this.protectedData(), so TS yells here. What works and what not:

class B extends A {
  public extractTest(anInstanceOfA: A, instanceOfB: B): string {
    anInstanceOfA.protectedData() // ✖, protected member of arg with base class 
    instanceOfB.protectedData() // ✔, protected member of arg with *same* class 
    this.protectedData(); // ✔, (derived) protected member via `this`
    return anInstanceOfA["protectedData"]() // escape-hatch with dynamic property access
  }
}

So you either can declare protectedData as public or use an escape-hatch, which will make protected members accessible via dynamic property access with bracket notation.

anInstanceOfA["protectedData"]()

Playground sample to try it out

Upvotes: 8

Related Questions