Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript not recognizing properties on the parent class?

Tags:

typescript

I have a basic inheritence like so:

export abstract class Animal
{
     constructor() {

     }

     makeSound() {
         alert(this.sound);
     }
}

export class Dog extends Animal
{
     public sound: string = "Woof!";

     constructor() {
         super();
     }
}

const dog = new Dog;
dog.makeSound(); // Woof!

I'm having an issue trying to get the above snippet working. Property prop does not exist on type Animal. However, it does exist on Dog, and since it is public, Animal should be able to reach prop via this.prop.

I tried the following:

  • Same as above - It doesn't compile. (Property prop does not exist on type Animal)
  • If I add public prop: any; to Animal, then prop becomes undefined and not Hello world.
  • If I add public abstract prop: any; to Animal, same thing happens.

The whole point of inheritence by using abstract classes is to share this scope.

How can I do it properly with Typescript?

like image 282
Aris Avatar asked Jan 10 '17 19:01

Aris


People also ask

How do I access parent class properties?

To access parent class attributes in a child class: Use the super() method to call the constructor of the parent in the child. The __init__() method will set the instance variables. Access any of the parent class's attributes or methods on the self object.

How do I declare a properties in TypeScript?

Parameter properties are declared by prefixing a constructor parameter with an accessibility modifier or readonly , or both. Using private for a parameter property declares and initializes a private member; likewise, the same is done for public , protected , and readonly .

Does TypeScript allow inheritance?

TypeScript supports single inheritance and multilevel inheritance. We can not implement hybrid and multiple inheritances using TypeScript. The inheritance uses class-based inheritance and it can be implemented using extends keywords in typescript.

How do you call a base class method in TypeScript?

You can call the base class constructor from the child class by using the super() which will execute the constructor of the base class. Example: Javascript.


1 Answers

I agree with JB Nizet. But you also have the ability to define sound as an abstract property. That way your base class knows about sound, and all extending classes have to implement the abstract property sound:

export abstract class Animal
{
    abstract sound: string; // Only change here, now your code works
    constructor() {

    }

    makeSound() {
        alert(this.sound);
    }
}

export class Dog extends Animal {
    public sound: string = "Woof!";

    constructor() {
        super();
    }
}

const dog = new Dog;
dog.makeSound(); // Woof!

The ability to define abstract properties came with TS 2.0: https://github.com/Microsoft/TypeScript/issues/4669

Update

The problem OP experienced with this approach, see comments, was that the abstract property was used in the constructor of the abstract base class. This will not work since the property is assigned the initial value from the deriving class first after the object is instantiated.

There is a github issue for this problem, where the solution is to simply error on access to abstract properties within the constructor of the abstract class.

like image 192
Alex Avatar answered Oct 14 '22 08:10

Alex