There appears to be a workaround that functions, even for return types, specifically with TypeScript version 4.02 by utilizing an interim class.
However, it should be noted that this method violates the Liskov substitution principle as it alters the return type and does not account for scenarios where the parameter is a string.
While it's interesting from a knowledge standpoint, I wouldn't endorse this approach in a code review since a subclass should seamlessly replace the base class without impacting functionality.
class Base {
public myMethod(myString: string): string {
return myString + myString;
}
}
// weaken
// inspired by comment here: https://github.com/microsoft/TypeScript/issues/3402#issuecomment-385975990
class Interim extends Base {
public myMethod(x: any): any { return super.myMethod(x); }
}
class Child extends Interim {
public myMethod(myNumber: number): number {
return myNumber * myNumber;
}
}
// we can have a helper/utility for this
function weaken(klass: { new(...args: any[]): any; }, key: string) {
return class extends klass {
[key](...args: any[]) { super[key](...args); }
}
}
class ChildOther extends weaken(Base, 'myMethod') {
public myMethod(myNumber: number): number {
return myNumber * myNumber;
}
}
console.log((new Child()) instanceof Base); // true
console.log((new ChildOther()) instanceof Base); // true
console.log(new Base().myMethod('str')); // strstr
console.log(new Child().myMethod(3)); // 9
console.log(new ChildOther().myMethod(3)); // 9