Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Supplied parameters do not match any signature of call target in wrapper method - Typescript

Ok I'm guessing I'm missing something really simple on this one.

Lets say I have multiple methods that repeat a lot of the same things like this:

    public getDepartments(id: number): ng.IPromise<IDepartmentViewModel[]> {
        this.common.loadStart();
        return this.unitOfWork.teamRepository.getDepartmentsForTeam(id).then((response: IDepartmentViewModel[]) => {
            this.common.loadComplete();
            return response;
        }).catch((error) => {
                this.common.loadReset();
                return error;
            });
    }

Tons of boilerplate for a single call to this.unitOfWork.teamRepository.getDepartmentsForTeam(id)

so I wanted to make a generic wrapper for the boilerplate such as:

private internalCall<T>(method: () => ng.IPromise<T>): ng.IPromise<T> {
        this.common.loadStart();
        return method().then((response: T) => {
            this.common.loadComplete();
            return response;
        }).catch((error) => {
            this.common.loadReset();
            return error;
        });
    }

Which I could then call like:

public getDepartments(id: number): ng.IPromise<IDepartmentViewModel[]> {
        return this.internalCall<IDepartmentViewModel[]>(this.unitOfWork.teamRepository.getDepartmentsForTeam(id));

But I get the following error:

Supplied parameters do not match any signature of call target:
Type '() => ng.IPromise<IDepartmentViewModel[]>' requires a call signature, but type 'ng.IPromise<IDepartmentViewModel[]>' lacks one.

What is the right way to pass my method into the other to call it with supplied parameters?

like image 346
John Avatar asked Sep 02 '14 20:09

John


3 Answers

This is a common mistake: you cannot pass a method function as a regular function since it requires the instance for the class as context. The solution is to use a closure:

function foo( func: () => any ) {
}
class A {
 method() : any {
 }
}
var instanceOfA = new A;

// Error: you need a closure to preserve the reference to instanceOfA
foo( instanceOfA.method ); 
// Correct: the closure preserves the binding to instanceOfA 
foo( () => instanceOfA.method() ); 

For a more complete example you can also see my snippet published here: http://www.snip2code.com/Snippet/28601/Typescript--passing-a-class-member-funct

like image 80
micurs Avatar answered Nov 14 '22 12:11

micurs


I needed to wrap the call so it was wrapped in a closure like so:

public getDepartments(id: number): ng.IPromise<IDepartmentViewModel[]> {
    return this.internalCall<IDepartmentViewModel[]>(
        () => { return this.unitOfWork.teamRepository.getDepartmentsForTeam(id); } // Wrapping here too
    );
like image 3
John Avatar answered Nov 14 '22 12:11

John


Only for documentation - I got this error when I accidentally called the wrong (existing) function with wrong parameters. Had to look into the errorous line in the packaged file .tmp/bla/bla/bla.ts to see the error.

like image 1
El Dude Avatar answered Nov 14 '22 10:11

El Dude