Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript abstract method overloading

I want to overload an abstract method within an abstract class like this:

abstract class Animal {

    public abstract communicate(sentence: string): void;
    public abstract communicate(notes: string[]): void;

}

class Human extends Animal {

    public communicate(sentence: string): void {
        // Do stuff
    }

}

class Bird extends Animal {

    public communicate(notes: string[]): void {
        // Do stuff
    }

}

However, Typescript gives an error, stating I incorrectly extend the base class (Animal)

Is there something I am doing wrong? Like expecting something to work which would work anyway according to OOP? Or is it something Typescript doesn't support?

Note: The type of the parameter can be entirely different types unlike in this example.

like image 678
Wilco Bakker Avatar asked May 15 '17 13:05

Wilco Bakker


People also ask

Does TypeScript allow method overloading?

TypeScript provides the concept of function overloading. You can have multiple functions with the same name but different parameter types and return type. However, the number of parameters should be the same.

Does TypeScript have abstract methods?

A TypeScript Abstract class is a class which may have some unimplemented methods. These methods are called abstract methods. We can't create an instance of an abstract class. But other classes can derived from abstract class and reuse the functionality of base class.

How do I create an abstract method in TypeScript?

Define an abstract class in Typescript using the abstract keyword. Abstract classes are mainly for inheritance where other classes may derive from them. We cannot create an instance of an abstract class. An abstract class typically includes one or more abstract methods or property declarations.


1 Answers

Like @DavidSherret said the sub-class must implement all the abstract class overloads, not just one of them. So you won't really be able to do what you want using abstract class overloads.

Since what you want is to have Bird and Human have a different communicate() param type, enforced by the compiler, I would use a generic type argument with type constraint:

abstract class Animal<C extends string | string[]> {
    public abstract communicate(communication: C): void;
}

class Human extends Animal<string> {
    public communicate(sentence: string): void { }
}

class Bird extends Animal<string[]> {
    public communicate(notes: string[]): void { }
}

class Bynar extends Animal<boolean> { // Error: 'boolean' does not satisfy the constraint 'string | string[]'.
    public communicate(bit: boolean): void { }
}

const human = new Human();
human.communicate("hello"); // OK
human.communicate(["hello"]); // Error

const bird = new Bird();
bird.communicate("hello"); // Error
bird.communicate(["hello"]); // OK

Tip: you can make use of TS 2.3 default type arguments here as well.

like image 72
Aaron Beall Avatar answered Sep 28 '22 02:09

Aaron Beall