Alter method signature for child class in Typescript?
Asked Answered
P

4

5

In the example below (Typescript, 1.7+), what would I have to change to allow B.callback to have a different signature than A.callback?

class A {
    callback(result: number) {
    }
}


class B extends A {
    callback(result: number, option: number) {
    }
}

Currently this gives test.ts(7,7): error TS2415: Class 'B' incorrectly extends base class 'A'.

In the real world my example is more complex, but I can dynamically (more or less) guarantee (based on some configuration) that the requested parameters will be there.

Postmistress answered 5/11, 2015 at 10:36 Comment(0)
F
5

Depending on the situation, the following solution may suffice too:

class A {
    callback(result: number) {
    }
}


class B extends A {
    callback(result: number, option?: number) { // make 'option' optional
    }
}
Findley answered 5/11, 2015 at 13:7 Comment(0)
O
4

This will never be allowed. You need to conform to the base class function signature because its polymorphism 101:

class A {
    callback(result: number) {
    }
}


class B extends A {
    callback(result: number, option?: number) {
    }
}

// Reason
var b = new B();
var a:A = b; // okay as its a subclass
a.callback(123); // If b didn't have that optional B.callback can blow up
Otway answered 5/11, 2015 at 23:17 Comment(2)
Well, yes, but one could argue that any parameter could be undefined at any time nonetheless, so a.callback(123) would still be a valid method call to b.Postmistress
would still be a valid method call to b Explicitly passing undefined is different from an implicit undefined. And if you find yourself passing an explicit undefined ... please consider making it an optional argumentOtway
P
0

I suspect this is not possible in TypeScript 1.6 and the upcoming 1.7. Either give B.callback() a new name, or add the parameter as an optional parameter in A.callback().

It feels kind of wrong from a traditional OOP standpoint, i.e. C#, Java. One should not be able to change the number of parameters in an overridden method. A reference to class A is be able to hold class B objects. If B adds a non-optional parameter to a method, calls to the method via the A reference would fail. This would be raised as an error by the compiler.

Porche answered 5/11, 2015 at 10:51 Comment(1)
From a traditional standpoint I'm with you. In my example though callback is passed into Angular (as a controller), and dynamically receives a number of parameters based on its configuration (which is set in B's constructor()).Postmistress
P
0

After some back and forth I think the best solution is currently:

class A {
    callback(result: number, ...rest: any[]) {
    }
}


class B extends A {
    callback(result: number, option: number) {
    }
}
Postmistress answered 5/11, 2015 at 12:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.