I don't know if it's possible to do what I pretend to do but here it goes as a quick example ...
A simple class, ABC, with an overloaded constructor using optional parameters:
export class ABC {
s:string = "";
n:number = 0;
constructor();
constructor(_s:string);
constructor(_n:number);
constructor(_arg?:string|number) {
if (typeof _arg == "string") {
this.s = <string>_arg;
} else if (typeof _arg == "number") {
this.n = <number>_arg;
} else {
console.log("no args!");
}
}
}
Then another one class, DEF, inheriting from ABC:
export class DEF extends ABC {
constructor(); constructor(_s:string); constructor(_n:number); constructor(_arg?:string|number) { super(_arg); }}
Typescript complains about DEF using super(_arg) with the following group of error messages:
No overload matches this call.
Overload 1 of 3, '(_s: string): ABC', gave the following error. Argument of type 'string | number' is not assignable to parameter of type 'string'. Type 'number' is not assignable to type 'string'.
Overload 2 of 3, '(_n: number): ABC', gave the following error. Argument of type 'string | number' is not assignable to parameter of type 'number'.
Type 'string' is not assignable to type 'number'.ts(2769) ABC.ts(10, 2): The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible.
How can I make DEF to inherit from ABC using its constructor with the optional arguments? Can we make the "overloads visible from the exterior" as mentioned at the last line?
Many thanks for your help!
-Francisco
Following jcalz suggestion (thanks!) here it is a bit more elaborate example with the reason I've posed the original question:
export class ABC {
constructor();
constructor(_arg1:string);
constructor(_arg1:number);
constructor(_arg1:string, _arg2:number);
constructor(_arg1:string, _arg2:string);
constructor(_arg1:number, _arg2:string);
// DO NOT ALLOW THE FOLLOWING!!!
// constructor(_arg1:number, _arg2:number);
// but here it says otherwise ...
constructor(_arg1?:string|number, _arg2?:string|number);
// ----------------------------------------------------
constructor(_arg1?:string|number, _arg2?:string|number) {
}
}
export class DEF extends ABC {
constructor(_arg1?:string|number, _arg2?:string|number) {
super(_arg1,_arg2);
}
}
This one allows us to build ABC(1,2) something it shouldn't be able to do, while checking it at compile time ... There will be some combinations of types that shouldn't be accepted by the constructor(s). How can it be done?