In typescript we can create create a function that wraps another function, and preserve all types of the wrapped function like this:
function boundCall<
THeadParams extends unknown[],
TTailParams extends unknown[], TReturn>(
f: (...args: [...THeadParams, ...TTailParams]) => TReturn, ...boundHeadParams: THeadParams
) {
return (...tailParams: TTailParams)=>{ return f(...boundHeadParams, ...tailParams)};
}
function noneGeneric(name: string, age: number, gender: "male" | "female") {
console.log(name, age, gender);
return gender;
}
const boundNoneGeneric = boundCall(noneGeneric, "classy");
const r1 = boundNoneGeneric(1 , "female");
which generates this d.ts file
"use strict";
function boundCall(f, ...boundHeadParams) {
return (...tailParams) => { return f(...boundHeadParams, ...tailParams); };
}
function noneGeneric(name, age, gender) {
console.log(name, age, gender);
return gender;
}
const boundNoneGeneric = boundCall(noneGeneric, "classy");
const r1 = boundNoneGeneric(1, "female");
but as soon as we intruce generics to this mix we loose all types:
function genericTest<TLast>(name: string, age: number, gender: "male" | "female", last: TLast) {
console.log(name, age, gender);
return last;
}
const boundGeneric = boundCall(genericTest, "classy"); // type error here
const r2 = boundGeneric(1, "female", {test: true})
here is the .d.ts for this one
declare function boundCall<THeadParams extends unknown[], TTailParams extends unknown[], TReturn>(f: (...args: [...THeadParams, ...TTailParams]) => TReturn, ...boundHeadParams: THeadParams): (...tailParams: TTailParams) => TReturn;
declare function genericTest<TLast>(name: string, age: number, gender: "male" | "female", last: TLast): TLast;
declare const boundGeneric: (...tailParams: unknown[]) => unknown;
declare const r2: unknown;
I expected boundGeneric
to preserve the types which should be a generic function itself:
type boundGeneric = <TLast>(age: number, gender: "male" | "female", last: TLast) => TLast
but I get:
declare const boundGeneric: (...tailParams: unknown[]) => unknown;
is there a way to preserve the types?
here is the full playground link: TS playground
thanks for your time wizards!