TypeScript Version: 2.0.3
Code
class A {
constructor(a: number, b: string) { }
}
class B extends A {
constructor(...args) {
super(...args) // Supplied parameters do not match any signature of call target.
}
}
Expected behavior:
It's possible to pass arguments to super constructor without specifying them explicitly.
E.g. when extending classes of external framework, like React, which calls constructors.
Actual behavior:
Error: Supplied parameters do not match any signature of call target
I think the compiler is correct to flag the example as non-type-safe. You could instantiate B with zero arguments, one argument, ten arguments, and each argument can be any type. Those same arguments will then be passed through to A's constructor. But A expects exactly two arguments of specific types, so this pattern is not type-safe at all.
You'd get the same error if you wrote new A(42) or new A(1, 'foo', true), even though B's constructor would allow any of those.
If the constructor of A can take an undetermined number of arguments, then it would make sense to use ...:
class A {
values: any[];
constructor(...args: any[]) {
this.values = args;
}
}
class B extends A {
constructor(...args: any[]) {
super(args);
}
}
However, in this case it looks like the number of arguments of A is determined. So it would be better to do the following:
class A {
constructor(a: number, b: string) {}
}
class B extends A {
constructor(...args: any[]) {
if (args.length < 2) throw new Error();
let a: number = args[0];
let b: string = args[1];
super(a, b);
}
}
If the number of constructor arguments in B can be determined, then I would recommend to avoid using ... on both A and B.
class A {
constructor(a: number, b: string) {}
}
class B extends A {
constructor(a: number, b: string) {
super(a, b);
}
}
The ... operator will save you writing some code but you are losing certain level of security provided by the type system.
For the record, if you just didn't write a constructor at all, TypeScript would just "inherit" the constructor. See here.
Most helpful comment
For the record, if you just didn't write a constructor at all, TypeScript would just "inherit" the constructor. See here.