DEV Community

Michal M.
Michal M.

Posted on • Updated on • Originally published at geodev.me

Own higher order functions implementation using TypeScript

JavaScript is mostly about functions. We can:
1) assign them to variables,
2) use as arguments to other functions,
3) return a function from a function.

Higher order function is a function that applies to point 2 or 3.
In this post, I'd like to show how I implemented my own versions of some built-in language higher order functions using TypeScript.
I did not cover Array.prototype.reduce in this post. Hopefully, I will implement this soon.

Interface

First, I create an interface to set a structure for my methods implementation. Notice that I use typescript generics here. An array can consist of items of different types and generics are a good solution for such situations. Thanks to it we make this implementation more reusable. We won't lose the information about the passed array type also.

 interface Array<T> {
    myForeach(cb: (element: T, index: number, arr: T[]) => void): undefined;
    myFilter(cb: (element: T, index: number, arr: T[]) => boolean): T[];
    myMap(cb: (element: T, index: number, arr: T[]) => T): T[];
}
Enter fullscreen mode Exit fullscreen mode

ForEach

Let's start with Array.prototype.forEach. This method executes a callback once for each element in the provided array.
Here's my version of it. Notice that returned value is undefined since this method does not return an array, like the other higher order functions we know from JavaScript.

 Array.prototype.myForeach = function<Each>(callback: (element: Each, index: number, arr: Each[]) => void): undefined {
    for (let i = 0; i < this.length; i++) {
        callback(this[i], i, this);
    }
    return undefined
}
Enter fullscreen mode Exit fullscreen mode

Map

Here we need to set the type for the returned (ChangedMapElem) array, not only the passed one.

 Array.prototype.myMap = function<MapElem, ChangedMapElem>(callback: (element: MapElem, index: number, arr: MapElem[]) => ChangedMapElem): ChangedMapElem[] {
    let mapped = [];
    for (let i = 0; i < this.length; i++) {
        mapped.push(callback(this[i], i, this))
    }

    return mapped;
}
Enter fullscreen mode Exit fullscreen mode

Filter

 Array.prototype.myFilter = function<FilterElem>(callback: (element: FilterElem, index: number, arr: FilterElem[]) => boolean): FilterElem[] {
    let filtered = [];
    for (let i = 0; i < this.length; i++) {
        if (callback(this[i], i, this)) filtered.push(this[i]);
    }

    return filtered;
}
Enter fullscreen mode Exit fullscreen mode

That's it. I made it just for practice, to solidify my JavaScript/TypeScript skills. I don't encourage you to use your own implementations of methods that are already built into the language. These are well optimized and opinionated so let's stick to language base principles and tools.

Top comments (0)