overexchange
overexchange

Reputation: 1

Child class variable referring Parent class object

Below is the syntax, using 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

For variable d, TypeScript supports Structural typing and type Dog has atleast properties(similar) that Mammal has, after overriding. So variable d can still point to Mammal type object until one more property is added in Dog type.

In TypeScript, How to avoid such pitfalls?

Upvotes: 1

Views: 537

Answers (1)

Oscar Paz
Oscar Paz

Reputation: 18312

There's no way to avoid it. Structural typing is a need in TypeScript for interoperability with JavaScript and JSON. Is a little price we've got to pay, and a consquence of TypeScript purpose, which is to add types to JavaScript while still being completely compatible with it and, especially, with existent codebase.

The only way to avoid it, in your example, would be to add something to Dog that Mammal does not have, or, maybe, to make Mammal an abstract class, so it can't be directly instantiated. In this case it would be logical, as you might create a new Dog, Cat, Horse ... but not just a new Mammal.

As pointed by Titian and Estus, an easy option if you don't want to make Mammal abstract and want to go the way of differentiating the classes even if you don't really want to add anything extra, would be to add an irrelevant private property without (almost) any effect at runtime:

private isDog: undefined;

Upvotes: 3

Related Questions