Learn how to specify types for the accumulated value and initial value when using the reduce function with an array in TypeScript

I am currently running this code on the typescriptlang.org (typescript playground)

After learning about the importance of types in TypeScript and how to use them in functions, I am having trouble adding specific types within this reduce method:

// Types for car
type Car = {
 name:string,
 age:number,
 registered: boolean
};

// Reduce function to calculate the total number of registered cars.

function totalRegisteredCars(cars:Car[]) {
 cars.reduce((acc:number , car:Car) => {
    if(car.registered === true ) {
        acc + 1;
    }
 },0);
}

var cars = [
{name:'vw' , age: 30, registered: true},
{name:'vw' , age: 32, registered: true},
{name:'Merc' , age: 25, registered: false},
{name:'bmw', age: 20, registered: false},
{name:'bmw' , age: 21, registered: true},
{name: 'ford', age: 31, registered: false},
{name: 'pinto', age: 43, registered: false},
{name: 'uno', age: 41, registered: true},
{name: 'ford', age: 30, registered: true},
{name: 'Mustang', age: 19, registered: false}
];

console.log(totalRegisteredCars(cars));

When testing this on https://www.typescriptlang.org/play, I encountered the following error:


Error message

No overload matches this call. Overload 1 of 3, '(callbackfn: (previousValue: Car, currentValue: Car, currentIndex: number, array: Car[]) => Car, initialValue: Car): Car', gave the following error.

Argument of type '(acc: number, car: Car) => void' is not assignable to parameter of type '(previousValue: Car, currentValue: Car, currentIndex: number, array: Car[]) => Car'. Types of parameters 'acc' and 'previousValue' are incompatible. Type 'Car' is not assignable to type 'number'.

Overload 2 of 3, '(callbackfn: (previousValue: number, currentValue: Car, currentIndex: number, array: Car[]) => number, initialValue: number): number', gave the following error. Argument of type '(acc: number, car: Car) => void' is not assignable to parameter of type '(previousValue: number, currentValue: Car, currentIndex: number, array: Car[]) => number'. Type 'void' is not assignable to type 'number'.


Question

Although I have specified my accumulator as a number and car as Car, why does the compiler show the above error?

I would like to understand why I cannot set a type to my accumulator as a number and how to properly assign types within a reduce function in the future.

Answer №1

The error occurs due to an issue in your reduce callback implementation. The callback should return the result of the reduce operation after iterating through every element in the array.

function totalRegisteredCars(cars: Car[]) {
 cars.reduce((acc:number , car:Car) => {
    let newReducedValue = acc;
    if(car.registered === true ) {
        newReducedValue = acc + 1;
    }
    return newReducedValue;
 }, 0);
}

To simplify the code, you can rewrite it like this:

cars.reduce((acc: number, car: Car) => acc + car.registered ? 1 : 0, 0);
// or simply use car.registered alone as JS will convert it to a number

Another observation is that the type signature of totalRegisteredCars is actually (cars: Car[]) => void, indicating no return statement in the function which reduces the array of Cars to a single number with no further action taken.

If your intention was to return a number from totalRegisteredCars function (and then log it), you should specify the return type explicitly:

function totalRegisteredCars(cars: Car[]): number {

This update will prompt a new error message:

A function whose declared type is neither 'void' nor 'any' must return a value. (2355)

In response, we rectify our code to align with the intended functionality while appreciating the benefits of TypeScript for providing such insights.

function totalRegisteredCars(cars: Car[]): number {
  return cars.reduce((acc, car) => acc + car.registered ? 1 : 0, 0);
}

In my latest example, I omitted type declarations within the lambda functions as the types are inferred based on context - the type of car matches cars, and the type of acc corresponds to the second argument of reduce: 0.

Lastly, if your goal is simply to count the registered cars in your array, a more straightforward approach could be:

cars.filter(car => car.registered).length

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Handling JSON Data in JavaScript

In the script below, I have a json object that is being processed: $http({ url: '/mpdValidation/mpdValidate', method: "POST", data: { 'message' : mpdData } ).then(function(response) { console.log(response.data ...

having difficulty sending the username and password from the HTML page to the controller in AngularJS

In my AngularJS controller, I am having trouble retrieving the values of the username and password fields after submitting the login form. Here is the HTML code for the form: <form class="form-signin" action="" method="post"> ...

Handling error reporting using JSON in jQuery AJAX post success

UPDATE: I have resolved the PHP errors mentioned in previous Answers, however, the issue still persists. I am attempting to implement an error message display in case of a failed POST request and a success message for successfully completed requests. Curr ...

Managing arrayBuffer in hapi.js: A Comprehensive Guide

I am struggling to upload an arrayBuffer to my server and save it to a file. On the client side, I am using axios, and on the server side, I have implemented Hapi js. However, I am facing difficulties in extracting data from the request in the Hapi handler ...

Exploring Jasmine's Powerful Spying and Mocking Capabilities in JavaScript Prototypes

Hey everyone, I need some help with a JavaScript issue. So, I have a file named FileA.js which contains a prototype called FileAObject.prototype along with a function named funcAlpha(). Here's a snippet of what it looks like: File = FileA function s ...

Unexpected Quote Will Not Appear

My random quote generator is not functioning properly, it should display a different quote on each click of the button. My colleagues are also facing the same issue. It was working fine when implemented in JavaScript, but after converting all the syntax to ...

Can halting an ajax function mid-process prevent it from finishing?

My objective is to convert a video using ffmpeg, which tends to take a considerable amount of time to complete. I'm considering sending an ajax request to the server for this task, but I don't want the user to have to wait until the video convers ...

Having trouble with the AWS S3 getSignedUrl looping function?

Could you assist me in sending two S3 pre-signed URLs for every key found in the [user.idKey, user.selfieKey] array within my Express route? I have confirmed that S3 is successfully obtaining the pre-signed URLs as they are logging to the console using th ...

Utilizing Azure SDK to send an email

In my Node.js project, I am currently utilizing azure-graph: const MsRest = require('ms-rest-azure'); const credentials = await MsRest.loginWithServicePrincipalSecret(keys.appId, keys.pass, keys.tenantId, { tokenAudience: 'graph' } ...

Capture the responseBody data within a Newman script from a Postman collection and save it to a

I'm trying to execute a script.js using newman with a locally saved postman collection. The call is successful in postman, returning a token in the response body that I need to access. I would prefer not to open postman every time just to get the res ...

Utilizing Async/Await to Streamline Google Maps Elevation Requests

I'm struggling to run this in a sequential manner. I've experimented with various methods like using Promise.all and getting stuck in callback hell, but what I really need is to obtain elevations for each point that has a valid altitude value (no ...

What is the best way to utilize the $('input').on('change', function() method within AngularJS?

I am working on creating a registration form page using AngularJS and I need to display the percentage completed. The form consists of over 50 fields, so I am looking for a simple way to implement this functionality. Below is a snippet of the code I have ...

Creating a string from values in a multidimensional array by utilizing parent-child relationships and generating dynamic SQL queries

This data represents a dynamic array with sample information that needs to be utilized to create an SQL query. I am working with VueJs + Laravel. Below is the updated array data along with the methods: [ { "operator": "AND", "rules": [ { ...

React Router Error: Hook call invalid. Remember to only use hooks inside the body of a function component

I am having an issue with my React app that uses react router. In Box.js, I am attempting to access the URL parameters but I am encountering the following error message: Invalid hook call. Hooks can only be called inside of the body of a function component ...

Intercept Axios Responses - Retrieving API Responses for HTTP Statuses that are not in the 200 range

I've set up a custom Axios instance with interceptors for handling responses. As per the Axios documentation, the success interceptor is triggered for 2xx statuses while the error interceptor handles any other status codes. My goal is to show an error ...

Using d3.js to showcase a horizontal stacked bar chart demonstration

After researching on Stack Exchange, I found a horizontal stacked bar example at: This example is based on: http://bl.ocks.org/mbostock/3943967 To understand the code better, I ran Bostock's example on my machine using SimpleHTTPServer, but I couldn ...

What is the method in JavaScript for a child function to trigger a Return statement in its parent function?

I have encountered a unique problem. I need to retrieve some data downloaded via ajax and return it, but neither async nor sync modes are fetching the data in time for the return. Is there a way to call the return from a child function to the parent func ...

Transferring information among various instances of a single controller (ng-controller)

I am relatively new to using Angular and I am facing a challenge with a seemingly simple task that is proving to be more complex within the framework. The issue at hand involves data manipulation, specifically with a variable named var1. I am modifying th ...

Node.js application hosted on Google App Engine is not including cookies in the HTTP header

I have successfully deployed a Node app on Google App Engine, where I am managing authorization through sessions in the backend. My postgres datastore is handled using connect-pg-simple, and I can confirm that sessions are being stored in the database. // ...

Bugs may occur when using the Google Chart API with varying data arrays despite using the same options

Trying to create a line chart using the Google Chart API, I encountered an issue. Everything seems to work fine when I use arrayToDataTable and the chart looks good. Check out the first example here However, when I populate a data object with the necessa ...