Error code TS7053 occurs when an element implicitly has an 'any' type because a string expression cannot be used to index an empty object

I have implemented a code snippet that sorts items into groups based on their first character.

For example, if the array of item looks like this:

  • {name: 'Foo'}
  • {name: 'Bar'}
  • {name: 'Baz'}

The expected result should be:

B: - Bar

  • Baz F: - Foo

To achieve this functionality, I am using a computed property in VueJS:

<script lang="ts">
const computedItems = computed(() => {
    if (!items.value) return {};
    const grouped = items.value.data.reduce((r, item) => {
        let group = item.name[0];
        if (!r[group]) r[group] = {group, children: [item]}
        else r[group].children.push(item);
        return r;
    }, {});
    return Object.keys(grouped).sort().reduce(
        (obj, key) => {
            obj[key] = grouped[key];
            return obj;
        },
        {} as Record<string, { group: string, children: Item[] }>
);
});
</script>

However, I am encountering this warning:

TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.   No index signature with a parameter of type 'string' was found on type '{}'.

This warning is displayed for the following lines:

if (!r[group]) r[group]...
else r[group]...
obj[key] = grouped[key];

The data source for these items is retrieved from an API call:

type ItemResult = { data: ItemData[], links?: any, meta?: any };


const {
    data: items,
} = await useLazyAsyncApi<ItemResult>(`/api/item`);

The structure of ItemData is defined as follows:

export type ItemData = {
    uuid: string;
    company: App.Domain.Company.Data.CompanyData;
};

export type CompanyData = {
    uuid: string;
    name: string;
    url: string | null;
    phone: string | null;
    email: string | null;
    created_at: string;
    deleted_at: string | null;
};

My question is: How can I address the issue where an expression of type 'string' cannot be used as an index here?

Although the code functions correctly, the TypeScript error persists.

Answer №1

It appears that there may be a missing type in your initial reduce() function call. Typescript may not recognize that the reduce initializer {} is of type

Record<string, { group: string, children: Item[] }>
:

    const grouped = items.value.data.reduce((r, item) => {
        let group = item.name[0];
        r[group] = r[group] || {group, children: []}
        r[group].children.push(item);
        return r;
    }, {} as Record<string, { group: string, children: Item[] }>); // <- HERE
    return Object.keys(grouped).sort().reduce(
        (obj, key) => {
            obj[key] = grouped[key];
            return obj;
        },
        {} as Record<string, { group: string, children: Item[] }>
    );

In addition to your question, you can optimize by sorting your data first before grouping to avoid an extra pass on the resultant grouped object:

    const grouped = items.value.data
       .sort((i1, i2) => i1.name.localeCompare(i2.name))
       .reduce((r, item) => {
          let group = item.name[0];
          r[group] = r[group] || {group, children: []}
          r[group].children.push(item);
          return r;
       }, {} as Record<string, { group: string, children: Item[] }>);

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

How can I modify the date format using the Google Ajax Feed API?

Currently, I am utilizing Google's AJAX Feed API to pull data from an RSS feed. However, I am curious about how to modify the date format. The current format fed by "datePublished" appears as follows: Sun, 29 Jan 2012 23:37:38 -0800 Is there a way t ...

A guide to validating arrays in Vue.js

I need help with the following data structure: data() { return { headings: ['id','remark'], rows: [ { id: 1, FirstName: 'Jhon', LastName: 'Doe&a ...

The Vue CLI project, using Typescript, is facing challenges with building and running Mocha tests

My Vue 2 project, created using Vue CLi, is encountering numerous errors. While it compiles fine for development purposes, running unit tests or building for production results in a cascade of issues. Displayed below are some sample errors, along with sni ...

Functionality of the Parameters Object

As I transition from using the params hash in Rails to learning Node/Express, I find myself confused about how it all works. The Express.js documentation provides some insight: 'This property is an array containing properties mapped to the named rout ...

Is there a problem with addEventListener returning false?

What does keeping the third parameter as false in the line below signify? var el = document.getElementById("outside"); el.addEventListener("click", modifyText, false); ...

Modal shows full JSON information instead of just a single item

This is a sample of my JSON data. I am looking to showcase the content of the clicked element in a modal window. [{ "id": 1, "companyName": "test", "image": "https://mmelektronik.com.pl/w ...

Dynamically update a form with steps using JQuery-steps and send all objects to the controller

In the context of a form, it is possible to dynamically add between 1 to n records before passing it to the controller with data. The following represents the ViewModel for the form: public class AddFieldDataViewModel { public int SampleID { get; se ...

A different approach to joining strings

Is there a different method to combine a '#' symbol like in the code snippet below? radioButtonID = '#' + radioButtonID; ...

Creating a span element to replace the list item class in a JavaScript Modal Pop-up

I recently set up a portfolio website that showcases my projects. When you click on a project, a modal window opens with a carousel gallery inside. On my .html page, the projects are organized like this: <li class="Project" data-modal="myModal_1"> ...

Guide on detecting errors when parameters are not provided with req.params in Node.js

My question revolves around a piece of code that I have been working on. Here is the snippet: const express = require('express') const app = express() app.get('/test/:name', (req, res) => { const {name} = req.params; res.send(`P ...

Links have a longer transition delay compared to the content

In a unique JavaScript function I've developed, the my-content-section-visible class is removed and replaced with my-content-section-hidden. This change is being made to hide a particular div using a smooth transition effect. The transition itself is ...

Ionic table data is manipulated by the Vuex store manager

Code: https://github.com/cbsmerveguel/ionicblank Hey everyone, I'm diving into the world of vuejs and vuejs with ionic for the first time. I wanted to experiment with a master-detail view, where there is a table on the master page and the details of ...

Incorporating CouchDB storage into a Node.js socket.io JSON data stream

Currently in the process of researching how to implement persistence for a real-time Twitter JSON feed in Node.js. The stream is set up and sending data to the client, but I'm struggling with storing this information in a CouchDB database so that it c ...

Using a Class Decorator in Typescript to Enhance Static Methods across all Classes

Imagine having a class filled with numerous static methods. The objective is to encapsulate each static method within a function. The specific aim is to handle async errors by applying .catch to every static method in the following manner: // Within user-r ...

Tips for preserving component state during page rerenders or changes

I created a counter with context API in React, and I'm looking for a way to persist the state even when the page is changed. Is there a method to store the Counter value during page transitions, similar to session storage? My app utilizes React Router ...

Tips for efficiently resolving and compiling a bug within an NPM package, ensuring it is accessible to the build server

This question may seem a bit unconventional. I am currently using an npm package that includes built-in type definitions for TypeScript. However, I have discovered a bug in these definitions that I am able to easily fix. My goal is to make this updated ve ...

Transforming a TypeScript enum into an array of objects

My enum is defined in this structure: export enum GoalProgressMeasurements { Percentage = 1, Numeric_Target = 2, Completed_Tasks = 3, Average_Milestone_Progress = 4, Not_Measured = 5 } However, I want to transform it into an object ar ...

How can you use JavaScript to identify resize or zoom changes across all ancestor DOM elements?

I have a DOM element that consists of a chart. <div id="plot1" class='plot-chart'></div> This specific DIV can be nested within various other DIVs. <div id="one" style="width:100%;height:100%;zoom:0.9;"> <div id="two"& ...

Is there a way to execute v-for once the created() lifecycle hook has finished running?

In my current project, I am faced with the challenge of including avatars in notifications. Despite my efforts, I have not been able to solve this issue independently. The Vue.js template below demonstrates how I have attempted to add avatars to each notif ...

Using RxJS to merge various HTTP requests into a unified and flattened observable array

Struggling with combining multiple http get requests simultaneously and returning them as a unified, observable array. In my current setup, the method returnNewCars() retrieves Observable<ICar[]> by executing a single http get request. However, in t ...