The original purpose of this simplified code was to create a generic method in typescript that receive a delegate and an object and returns a new delegate whose signature should be the same of the passed in delegate BUT the "this" context would become the passed in object.
As pseudocode it should be something like this: f(del(args: ...parameters), context) => del(this: typeof context, args: ...parameters).
I tried a few approaches and all failed.
The following code was the attempt that seemed the most promising, but by the end it failed too.
In the code I did highlight my issue. Basically the typescript compiler is not able to infer the type of the arg1 and arg2 automatically looking at the signature of methodWithDelegate function.
Is there an explanation for it?
Is there a solution?
function createDelegate<TContext extends Object, TReturn, A>(fn: (a: A) => TReturn, context: TContext): (this: TContext, a: A) => TReturn
function createDelegate<TContext extends Object, TReturn, A, B>(fn: (a: A, b: B) => TReturn, context: TContext): (this: TContext, a: A, b: B) => TReturn
function createDelegate<TContext extends Object, TReturn, A, B, C>(fn: (a: A, b: B, c: C) => TReturn, context: TContext): (this: TContext, a: A, b: B, c: C) => TReturn
function createDelegate<TContext extends Object, TReturn, A, B, C>(instance: any, funct: Function): any
{
return <any>funct.bind(instance);
}
function methodWithDelegate(delegate: (this: string, val1: string, val2: string) => void)
{
//delegate invokation
}
methodWithDelegate(function (val1, val2)
{
// OK. val1 and val2 are inferred to be strings.
val1.substring(2);
});
methodWithDelegate(createDelegate(function (val1, val2)
{
// ISSUE: val1 and val2 are not inferred to be strings. they remain of type any
val1.substring(2);
}, "CONTEXT"));