angulartypescriptfor-loopindexing

Type 'string' can't be used to index type 'Object' with for loop


 getAllstudents(stdnt: string){
    let clsss=new Object();
    this.clssservice.getclsss(stdnt)
    .subscribe(
      stndt =>{
        for(let key in stndt ){
          clsss=stdnt[key];
          clsss['$key']=key;

export class Clsss {
    $key!: string; }

error 1:

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

(parameter) stndt string can't be used to index type Object.

error 2:

Element implicitly has an 'any' type because expression of type '"$key"' can't be used to index type 'Object'. let clsss: Object

I tried to use : string, type of string, key of string, as string but these solutions did not work.


Solution

  • The issues with the code are as follows.

    1. We have a shadowed property stndt which is set at the top of the function, as well as the subscribe, so you might be getting type issues.
    2. We have to create a separate interface or class, that is for the API call data returned by service (ServiceResponse)
    3. For solving the indexing issues, we can set a index type for the class/interface in typescript like [key: string]: Clsss[keyof Clsss]; where we say that the key is a string and the value will be the properties of the class
    4. Instead of instantiating an Object, just instantiate your class instead (let clsss: Clsss = new Clsss();).

    Full Code:

    import { Component, Injectable, inject } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    import { Observable, of } from 'rxjs';
    import 'zone.js';
    
    export class Clsss {
      [key: string]: Clsss[keyof Clsss];
      $key?: string;
      // Other interface props here!
    }
    
    export class ServiceResponse {
      [key: string]: ServiceResponse[keyof ServiceResponse];
      // Other interface props here!
    }
    
    @Injectable({
      providedIn: 'root',
    })
    export class ClssService {
      getclsss(something: any): Observable<ServiceResponse> {
        return of({}) as Observable<ServiceResponse>;
      }
    }
    
    @Component({
      selector: 'app-root',
      standalone: true,
      template: `
        <h1>Hello from {{ name }}!</h1>
        <a target="_blank" href="https://angular.dev/overview">
          Learn more about Angular
        </a>
      `,
    })
    export class App {
      name = 'Angular';
      clssservice = inject(ClssService);
    
      getAllstudents(stdnt: string) {
        let clsss: Clsss = new Clsss();
        this.clssservice.getclsss(stdnt).subscribe((stndtResponse: ServiceResponse) => {
          for (let key in stndtResponse) {
            clsss = stndtResponse[key];
            clsss['$key'] = key;
          }
        });
      }
    }
    
    bootstrapApplication(App);
    

    Stackblitz Demo