Переменная дочернего класса, ссылающаяся на объект родительского класса - PullRequest
0 голосов
/ 30 апреля 2018

Ниже приведен синтаксис с использованием TypeScript,

interface Animal{
    eat():void;
    sleep():void;
}

class Mammal implements Animal{

    constructor(private name:string){
        console.log(this.name, "is alive");
    }

    eat(){
        console.log("Like a mammal");
    }

    sleep(){
        console.log("Like a mammal");
    }
}

class Dog extends Mammal{
    eat(){
        console.log("Like a dog")
    }
}

let m: Mammal = new Dog("Prisca"); // looks fine
let d: Dog = new Mammal("abomination"); // This also works

Для переменной d TypeScript поддерживает структурную типизацию, а тип Dog имеет как минимум свойства (аналогичные), которые Mammal имеет после переопределения. Таким образом, переменная d может по-прежнему указывать на объект типа Mammal, пока в типе Dog не будет добавлено еще одно свойство.

В TypeScript, как избежать таких ловушек?

1 Ответ

0 голосов
/ 30 апреля 2018

Нет способа избежать этого. Структурная типизация необходима в TypeScript для взаимодействия с JavaScript и JSON. Это небольшая цена, которую мы должны заплатить, и следствие цели TypeScript, которая заключается в добавлении типов в JavaScript, при этом будучи полностью совместимым с ним и, особенно, с существующей кодовой базой.

Единственный способ избежать этого, в вашем примере, это добавить что-то к Dog, которого Mammal не имеет, или, может быть, сделать Mammal абстрактным классом, чтобы его нельзя было непосредственно создан. В этом случае это было бы логично, так как вы можете создать новый Dog, Cat, Horse ... но не просто новый Mammal.

Как указали Тициан и Эстус, простой вариант, если вы не хотите делать Mammal абстрактным и хотите пойти по пути дифференциации классов, даже если вы действительно не хотите добавлять ничего лишнего, будет добавить нерелевантную частную собственность без (почти) какого-либо эффекта во время выполнения:

private isDog: undefined;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...