Skip to content

Instantly share code, notes, and snippets.

@rauschma
Last active January 29, 2025 13:07
Show Gist options
  • Save rauschma/b105aa1fd6c66878b25066f17ad810c6 to your computer and use it in GitHub Desktop.
Save rauschma/b105aa1fd6c66878b25066f17ad810c6 to your computer and use it in GitHub Desktop.
Typing partial application in TypeScript
//========== Testing types ==========
const expectType = <Type>(_: Type): void => void 0;
type TypeEqual<Target, Value> = (<T>() => T extends Target
? 1
: 2) extends <T>() => T extends Value ? 1 : 2
? true
: false;
//========== applyPartial ==========
function applyPartial<
Func extends (...args: any[]) => any,
InitialArgs extends unknown[],
>(func: Func, ...initialArgs: InitialArgs) {
return (...remainingArgs: RemainingArgs<Func, InitialArgs>)
: ReturnType<Func> => {
return func(...initialArgs, ...remainingArgs);
};
}
//----- Test -----
function add(x: number, y: number): number {
return x + y;
}
const add3 = applyPartial(add, 3);
expectType<TypeEqual<
typeof add3,
// The parameter name is preserved!
(y: number) => number
>>(true);
//========== Utility type ==========
type RemainingArgs<
Func extends (...args: any[]) => any,
InitialArgs extends unknown[],
> =
Func extends (...args: [...InitialArgs, ...infer TrailingArgs]) => unknown
? TrailingArgs
: never
;
//----- Test -----
expectType<TypeEqual<
RemainingArgs<typeof add, [number]>,
[y: number]
>>(true);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment