An issue arises with the bind signature:
bind(this: Function, thisArg: any, ...argArray: any[]): any;
The return type of bind
for a function is any
. However, curry
still functions properly because any
can be converted to any other type. Therefore, the first overload declaration of curry
is utilized:
curry<T1, R>(func: (t1: T1) => R, arity?: number): CurriedFunction1<T1, R>;
In this case, T1
and R
are inferred as {}
.
This discrepancy highlights the need to avoid using bind
as it leads to loss of type information. Crafting a universally type-safe version of bind
proves challenging due to its ability to bind both this
and function arguments. However, a simple version that solely binds this
while preserving type info is feasible:
function typedThisBind<T1, T2, T3, T4, R>(fn: (t: T1, t2: T2, t3: T3, t4 : T4) => R, thisArg: any) : typeof fn
function typedThisBind<T1, T2, T3, R>(fn: (t: T1, t2: T2, t3: T3) => R, thisArg: any) : typeof fn
function typedThisBind<T1, T2, R>(fn: (t: T1, t2: T2) => R, thisArg: any) : typeof fn
function typedThisBind<T1, R>(fn: (t: T1) => R, thisArg: any) : typeof fn
function typedThisBind<R>(fn: () => R, thisArg: any) : () => R
function typedThisBind(fn: Function, thisArg: any) : any {
return fn.bind(thisArg);
}
By employing this modified version of bind, all functionalities should operate as anticipated (for functions with up to 5 arguments, additional parameters can be easily included):
class Foo {
method(a: number, b: number) {}
m(){
const curried = curry(typedThisBind(this.method, this));
const getSomething = curried(0, 0); // Functions as expected.
}
}