Search code examples
javascripttypescriptabstract-classtypescript-typings

Call an abstract method with prototype


I have an abstract class with an abstract method. I discovered that Typescript won't throw any error if I called the method with prototype and call. For exmaple:

abstract class Human{
    age: string;
    constructor(age: string){
        this.age = age;
    }
    abstract name(): void
}

class Human1 extends Human{
    constructor(age: string){
        super(age);
        this.name()
        
    }
name(): void {
    Human.prototype.name.call(this); // this is allowed despite that name is undefined/abstract
    let a = "do something";
    }
}

let a = new Human1("23")

Is there a way to make Typescript throw an error here?


Solution

  • I discovered that Typescript won't throw any error if I called the method with prototype and call.

    Yes, TypeScript is pretty bad at typing prototype objects. It thinks that Human.prototype has the type Human1, and for that it only considers the public interface. The abstract modifier is only affecting subclass implementations.

    Is there a way to make Typescript throw an error here?

    Yes, don't use .call to call the parent method. There's the super keyword for that:

    name(): void {
        super.name(); // this errors
        let a = "do something";
    }
    

    (playground demo)

    This does not compile but throws the error "Abstract method 'name' in class 'Human' cannot be accessed via super expression. (ts 2513)" as expected.

    1: Notice also that it thinks Human.prototype.age is a number, and that Human.prototype.constructor is any Function and not typeof Human.