Rajath
Rajath

Reputation: 2981

Typescript is showing error if I try to access the property value dynamically using square brackets in Angular

How to Fix No index signature with a parameter of type 'string' issue in Angular

Getting ESLint error here : Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Client'. No index signature with a parameter of type 'string' was found on type 'Row'

dynamic-table.component.html

<table>
  <tr>
    <th *ngFor="let i of headers">
      {{i.name}}
    </th>
  </tr>
  <tr *ngFor="let row of rows">
    <td *ngFor="let head of headers">
      {{row[head.name]}} <!-- Getting ESLint error here : Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Client'.
  No index signature with a parameter of type 'string' was found on type 'Row'. -->
    </td>
  </tr>
</table>

dynamic-table.component.ts

interface Header {
 displayName: string,
 name: string
}

interface Row {
 empId: string,
 empName: string,
 salary: string
}

@Component({
  selector: "dynamic-table",
  templateUrl: "./dynamic-table.component.html",
  styleUrls: []
})
export class DynamicTableComponent {
  title = "Dynamic Table";

  headers: Header[] = [];
  rows: Row[] = [];

  constructor() {
    this.headers = [
      {
        displayName: "Emp Name",
        name: "empName"
      },
      {
        displayName: "Emp ID",
        name: "empId"
      },
      {
        displayName: "Salary",
        name: "salary"
      }
    ];
    this.rows = [
      {
        empId: "1",
        empName: "red",
        salary: "10000"
      },
      {
        empId: "1",
        empName: "red",
        salary: "50000"
      },
      {
        empId: "1",
        empName: "red",
        salary: "30000"
      }
    ];
  }
}

Upvotes: 0

Views: 623

Answers (1)

lbsn
lbsn

Reputation: 2412

In version 13 Angular CLI enables TypeScript strict mode on newly created projects. That enables (among other) the noImplicitAny flag.

Since header.name could be any string TypeScript has no way to know the type of row[header.name] so it's assigning it to any (and is complaining about that).

To solve the issue you can do any of the followings:

(1) declare an index signature on your Row interface:

interface Row {
  [key: string]: string,
  empId: string,
  empName: string,
  salary: string
}

Here you're telling TS that any property on Row accessed through a string will have a string type.

(2) restrict the type of Header.name to a literal union of Row's keys:

interface Header {
    displayName: string,
    name: keyof Row
}

Here you're declaring the type of Header.name as "empId" | "empName" | "salary" (no other value will be allowed).

(3) Disable the noImplicitAny flag by setting "noImplicitAny": false in your tsconfig.json (obviously this will disable the check at all).

Upvotes: 1

Related Questions