Reputation: 6844
Let's say I'm using an external library that provides the following class:
Class A {
...overloads types
doSomething(param, params) {
}
}
I want to override the super
method and provide my implementation, but I want to keep the types of the original. (including the overloads)
Class B extends A {
doSomething(param, params) {
// ...some logic
super.doSomething();
}
}
There is a way to do this with Typescript?
Upvotes: 1
Views: 51
Reputation: 8295
Should work fine exactly how you described it:
class A {
test() {
return 'from class A';
}
}
class B extends A {
test() {
return super.test() + ' and from class B';
}
}
you can play with it here on the typescript playground
To keep the args:
class A {
test(a: number) {
return `from class A ${a}`;
}
}
class B extends A {
test: A['test'] = (...args) => {
return super.test(...args) + ' and from class B';
}
}
and if you want it on the prototype:
class A {
test(param: number | string): void {
console.log(param);
}
}
type ArgumentsType<T> = T extends (...args: infer A) => any ? A : never;
class B extends A {
test(...args: ArgumentsType<A['test']>): ReturnType<A['test']> {
return super.test(...args);
}
}
Upvotes: 2
Reputation: 249536
Typescript does not infer parameter types based on the base type. The way things go is that the class is typed independently and then checked for inconsistencies with the base class. This also means there is no way to keep the overloads from the base class.
One way you could reduce the syntax is to assign to the prototype of B
class A {
doSomething(param: number, params: number)
doSomething(param: string, params: string)
doSomething(param: number | string, params: number | string) {
alert ("A")
}
}
class B extends A {
}
B.prototype.doSomething = function doSomething(this: B, param, params) {
alert("B");
A.prototype.doSomething.call(this, arguments);
}
new A().doSomething(0, 0)
new B().doSomething(0,0)
This way the types of the parameters are inferred and if you have an explicit annotation for this
it will be typed appropriately inside the function. Only drawback is you have to use a rather large syntax to issue the super call
Upvotes: 1
Reputation: 2822
The syntax would be super awkward and you are no longer will be leveraging prototype, but rather defining the method in the constructor which might have performance implications but this works:
class A {
doSomething(param: number): void
doSomething(param: string): void
doSomething(param: number | string): void {
}
}
class B extends A {
doSomething: A["doSomething"] = () => {
A.prototype.doSomething.call(this)
}
}
const b = new B();
b.doSomething(42) // ok
b.doSomething("foo") // ok
b.doSomething(false) // error
Upvotes: 0