The reducer method is a very useful array method. It lets you process an array item by item, reducing this to one variable. By default, the return type of the reducer is a single item of whatever your array returns. You can change the return type by providing a different initial value to reduce. In this article I’ll be talking about using reduce in TypeScript, but we also have an article covering the particulars of using the method in React here.

Introduction

Let’s take a look at the signature for reduce:

Array<T>.reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T

Firstly reduce is a generic method. It uses the type of the array you’re calling reduce on to decide the type of the other parameters.

Our first parameter is a function that gets called for each item in the array. As parameters, this function takes:

  • The previous value, or the accumulator. Whatever you return from the last iteration
  • The current value; the value the reduce is currently on
  • The current index of the current value
  • The actual source array

Then reduce also accepts an optional parameter of an initial value to use for the previous value/accumulator.

Here’s a simple example using reduce to find the longest word in an array:

const words = [
    'apple',
    'banana',
    'banana',
    'carrot',
    'carrot',
    'carrot',
    'dinosaur',
    'dinosaur',
    'elephant',
];

const longestWord = words.reduce((prevWord, currWord) => {
    if (prevWord.length > currWord.length) return prevWord;
    return currWord;
});

console.log(longestWord); //elephant

This is the simplest use case for reduce, and processing the array from a list of strings to 1 string. The logic for the callback function is simple, just returning whichever is longer of our current longest word and the current word.

Different Return Types

One very useful part of the reduce method is that it doesn’t always expect you to return the same type as you’re reducing, even if it isn’t an array. By default, it will assume you’re using reduce to transform an array T[] into 1 T, but we can change this by providing a different initial value to the reducer.

This gives us a very powerful tool, like map, except what we output doesn’t have to be an array.

Word Frequency

Let’s use reduce to build a function that works out the frequencies for words in an array. Here’s the input/output we’re expecting:

Here’s my implementation:

const frequencies = words.reduce((freq, word) => {
    const wordFreq = freq.get(word) ?? 0;
    return freq.set(word, wordFreq + 1);
}, new Map<string, number>());

The steps are simple.

  • First, we provide an empty map to the reduce function, to use as the start value.
  • Then we use reduce to iterate through the array
  • We get the frequency value from the map
  • I’m using the null coalescing operator. If the value doesn’t exist the get will return undefined, and the operator returns the default value of 0
  • If it does exist, wordFreq gets set to the actual value
  • Then all we need to do is increase the frequency by 1, and store the new value. set() returns the new map, so we can shorten the setting and returning to 1 line.

The key part about this is that the return type of the callback function we provide to reduce, as well as the return type of the whole function, both depend on the starting value. By default, this will be the value of whatever your starting array stores, but TypeScript lets you be as flexible with this as you like.

Conclusion

Thanks for reading this article on array reducing in TypeScript. Hopefully, these examples helped you out. If you liked the content, or if you’re having any issues, feel free to leave a comment below!

Avatar photo
👋 Hey, I'm Omari Thompson-Edwards
Hey, I'm Omari! I'm a full-stack developer from the UK. I'm currently looking for graduate and freelance software engineering roles, so if you liked this article, reach out on Twitter at @marile0n

💬 Leave a comment

Your email address will not be published. Required fields are marked *

We will never share your email with anyone else.