Skip to content

Instantly share code, notes, and snippets.

@orion55
Created August 28, 2023 05:30
Show Gist options
  • Select an option

  • Save orion55/da4c04c64347c6d9058641a7989fd2f5 to your computer and use it in GitHub Desktop.

Select an option

Save orion55/da4c04c64347c6d9058641a7989fd2f5 to your computer and use it in GitHub Desktop.
toFunctional
function toFunctional<T extends Function>(func: T): Function {
const fullArgCount = func.length;
function createSubFunction(curriedArgs: unknown[]) {
return function(this: unknown) {
const newCurriedArguments = curriedArgs.concat(Array.from(arguments));
if (newCurriedArguments.length > fullArgCount) {
throw new Error('Too many arguments');
}
if (newCurriedArguments.length === fullArgCount) {
return func.apply(this, newCurriedArguments);
}
return createSubFunction(newCurriedArguments);
};
}
return createSubFunction([]);
}
interface MapperFunc<I, O> {
(): MapperFunc<I, O>;
(input: I[]): O[];
}
interface MapFunc {
(): MapFunc;
<I, O>(mapper: (item: I) => O): MapperFunc<I, O>;
<I, O>(mapper: (item: I) => O, input: I[]): O[];
}
export const map = toFunctional(<I, O>(fn: (arg: I) => O, input: I[]) => input.map(fn)) as MapFunc;
interface FiltererFunc<I> {
(): FiltererFunc<I>;
(input: I[]): I[];
}
interface FilterFunc {
(): FilterFunc;
<I>(filterer: (item: I) => boolean): FiltererFunc<I>;
<I>(filterer: (item: I) => boolean, input: I[]): I[];
}
export const filter = toFunctional(<I>(fn: (item: I) => boolean, input: I[]) => input.filter(fn)) as FilterFunc;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment