3

I'm trying to extend a class in an Angular project and I want to pass arguments to the parent class using the rest/spread syntax of ES2015 like the answer to this question

constructor(...args) {
    super(...args);
}

but I get an error Supplied parameters do not match any signature of call target and my app won't compile.

I made a contrived example using the typescript playground. Does anyone know how to get this to work without having to explicitly write the arguments of the parent class methods?

UPDATE: As pointed out by Teddy Sterne I actually don't need to use this for the constructor because it has the same arguments. I actually want to use this for a method that returns an observable. I want to catch errors by overriding the method and returning super.parentMethod(...args).catch(/* deal with error */)

Devin Crossman
  • 7,454
  • 11
  • 64
  • 102
  • The `Greeter` constructor takes in a `string`, passing an `any[]` array into a function expecting a `string` isn't expected to work. What are you trying to do? – Paarth Jul 05 '17 at 17:38
  • https://es6console.com/j4rasbut/ this works in ES6 but not in typescript. I guess it's because of the type checking? – Devin Crossman Jul 05 '17 at 17:48
  • Does it work if you just do `super(args)`? – Reactgular Jul 05 '17 at 17:58
  • @Paarth he's not passing an array into the super. He's forwarding the function parameters. I suspect this is a TypeScript limitation. – Reactgular Jul 05 '17 at 18:00

3 Answers3

2

Another workaround would be to use the built-in ConstructorParameters Type Helper.

class A {
    constructor (foo: number, bar: string) {}
}


class B extends A {
    constructor (...args: ConstructorParameters<typeof A>) {
        super(...args);
    }
}
tenbits
  • 7,568
  • 5
  • 34
  • 53
1

This question was asked and answered in this issue: https://github.com/Microsoft/TypeScript/issues/11679

You are correct assuming it's because of type checking. Lets assume the parent constructor expects a fixed number of parameters. At the point super(...args) is declared, the compiler doesn't know the actual number of passed parameters. Therefore it flags it as unsafe.

tony
  • 1,274
  • 1
  • 11
  • 27
0

If the Child has the exact same parameters to the constructor as the Parent then you do not need to specify the constructor. The dependencies will be injected that are required by the parent and the parent's constructor will be call implicitly.

class ParentClass {
    constructor(dep1: Dep1, dep2: Dep2) { }
}

class ChildClass {

}

If the child has additional dependencies then you will have to re-specify them and then pass them to the Parent's constructor inside the Child's constructor.

class ParentClass {
    constructor(dep1: Dep1, dep2: Dep2) { }
}

class ChildClass {
    constructor(dep1: Dep1, dep2: Dep2, dep3: Dep3) {
        super(dep1, dep2);
    }
}
Teddy Sterne
  • 13,774
  • 2
  • 46
  • 51
  • you are correct, I actually don't need to use this for the constructor rather for a method that returns an observable. I want to catch errors by overriding the method and returning super.parentMethod(...args).catch(/* deal with error */) – Devin Crossman Jul 05 '17 at 18:06