Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override method with different argument types in extended class - Typescript

I want to override a method and pass different argument types to it:

class Base {
    public myMethod(myString: string): undefined {
        return;
    }
}

class Child extends Base {
    public myMethod(myNumber: number): undefined {
        return super.myMethod(String(myNumber));
    }
}

Yet this yields a typescript error:

Property 'myMethod' in type 'Child' is not assignable to the same property in base type 'Base'. Type '(myNumber: number) => undefined' is not assignable to type '(myString: string) => undefined'. Types of parameters 'myNumber' and 'myString' are incompatible. Type 'string' is not assignable to type 'number'.

Is there a way to do this without creating a typescript error?

like image 856
A_A Avatar asked Jun 06 '18 20:06

A_A


People also ask

Can you override a method from extended class?

"The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method that it overrides.

Can you override methods in TypeScript?

When a method is marked with override , TypeScript will always make sure that a method with the same name exists in a the base class. This member cannot have an 'override' modifier because it is not declared in the base class 'SomeComponent'.

How do you override a class property in TypeScript?

To override a class method in TypeScript, extend from the parent class and define a method with the same name. Note that the types of the parameters and the return type of the method have to be compatible with the parent's implementation.

Can we override private method in TypeScript?

Using protected is the correct way to solve this! But if you have no access to the parent class (e.g. because it is within a library) you also could overwrite private class member-function in the constructor.


2 Answers

There is not a way to do this*. In TypeScript, inheritance implies subtyping, so you can't inherit from a base class while not being a valid subtype of it.

* Technically not true but I'm not going to mention them because they're gross hacks that you shouldn't do.

like image 184
Ryan Cavanaugh Avatar answered Sep 24 '22 12:09

Ryan Cavanaugh


As mentioned by others this is not a good idea because you break Liskov substitution.

What you can easily do, is provide an override that takes both string and number. This allows your class to still be used wherever the base class is expected.

class Base {
     public myMethod(myString: string): undefined {
         return;
     }
 }

class Child extends Base {
    public myMethod(myNumberOrString: number | string): undefined {
        if (typeof myNumberOrString === 'number') {
            return super.myMethod(String(myNumberOrString));
        } else {
            return super.myMethod(myNumberOrString);
        }
    }
}
like image 36
Titian Cernicova-Dragomir Avatar answered Sep 24 '22 12:09

Titian Cernicova-Dragomir