Доступ к защищенному методу из другого экземпляра с тем же родительским классом в машинописи - PullRequest
1 голос
/ 20 марта 2020

Я портирую код с PHP на NodeJs (машинопись). И я наткнулся на следующий PHP код (упрощенно)

<?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);

Запуск его в песочнице приводит к «доступному» эхо.

Я написал тот же код в Typescript, но это не похоже на работу ...

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));

Ошибка: свойство 'protectedData' защищено и доступно только через экземпляр класса 'B'. (2446)

Есть ли способ достичь этого в Typescript или есть большая разница между защищенными методами в PHP и Typescript?

1 Ответ

2 голосов
/ 20 марта 2020

Из документов :

Защищенный модификатор действует во многом как закрытый модификатор, за исключением того, что члены, объявленные защищенными , также доступны в производных классах .

В вышеприведенном случае вы используете protectedData в качестве метода из параметра функции anInstanceOfA, который имеет базовый тип A. Но вы не имеете доступа к protectedData в производном классе B по this.protectedData(), поэтому TS кричит здесь. Что работает, а что нет:

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
  }
}

Таким образом, вы можете либо объявить protectedData как public, либо использовать escape-люк, который сделает protected членов доступными через динамический c доступ к свойству с помощью Обозначение в скобках.

anInstanceOfA["protectedData"]()

Пример игровой площадки, чтобы попробовать его

...