185

Im getting this compilation error in my Angular 2 app:

TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.

The piece of code causing it is:

getApplicationCount(state:string) {
    return this.applicationsByState[state] ? this.applicationsByState[state].length : 0;
  }

This however doesn't cause this error:

getApplicationCount(state:string) {
    return this.applicationsByState[<any>state] ? this.applicationsByState[<any>state].length : 0;
  }

This doesn't make any sense to me. I would like to solve it when defining the attributes the first time. At the moment I'm writing:

private applicationsByState: Array<any> = [];

But someone mentioned that the problem is trying to use a string type as index in an array and that I should use a map. But I'm not sure how to do that.

Thans for your help!

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Ole Spaarmann
  • 15,845
  • 27
  • 98
  • 160
  • 4
    If you are trying to define a dictionary (with string keys), use type `{[key: string]: any}` – Harry Ninh Nov 01 '16 at 10:43
  • Now I'm getting `TS2339: Property 'size' does not exist on type '{ [key: string]: any; }'.` when trying to get the number of elements with `this.availableStates.size`. – Ole Spaarmann Nov 01 '16 at 10:47

5 Answers5

153

If you want a key/value data structure then don't use an array.

You can use a regular object:

private applicationsByState: { [key: string]: any[] } = {};

getApplicationCount(state: string) {
    return this.applicationsByState[state] ? this.applicationsByState[state].length : 0;
}

Or you can use a Map:

private applicationsByState: Map<string, any[]> = new Map<string, any[]>();

getApplicationCount(state: string) {
    return this.applicationsByState.has(state) ? this.applicationsByState.get(state).length : 0;
}
Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299
122

Not the OP's direct issue but for users encountering this error for libraries not under their control, one can suppress this error is by adding:

{
  ...
  "suppressImplicitAnyIndexErrors": true,
  ...
}

to the tsconfig.json file.


Deprecation Notice for configurations in TypeScript v5.5.

These configurations will continue to "work" until TypeScript 5.5, at which point they will be removed entirely. In TypeScript 4.9.5+, 5.0, 5.1, 5.2, 5.3, and 5.4, you can specify ignoreDeprecations: "5.0" to silence this warning.

Robert Brisita
  • 5,461
  • 3
  • 36
  • 35
  • 9
    You are missing the point of using a library 'not under your control'. I still stand by my original comment; as the topic subject is the error users will see and search for regardless of the OP's description. – Robert Brisita Oct 08 '19 at 08:42
  • 4
    OP wasn't asking about libraries not under their control, and you didn't mention it in your answer. If you had said "In your case you shouldn't do this, but for other people that have this error in code that isn't under your control then you can suppress the error as follows....", then that would have been fine and got my upvote. – Timmmm Oct 08 '19 at 09:55
  • 1
    Option 'suppressImplicitAnyIndexErrors' is deprecated and will stop functioning in TypeScript 5.5. Specify compilerOption '"ignoreDeprecations": "5.0"' to silence this error.ts – mercury Mar 16 '23 at 20:10
  • Thank you for the insight! Will update with link to GitHub issue. – Robert Brisita Mar 20 '23 at 01:43
72

I used this to get around it so I could use the window object.

//in js code somewhere
window.DataManager = "My Data Manager";


//in strict typescript file
let test = (window as { [key: string]: any })["DataManager"] as string;
console.log(test); //output= My Data Manager
Dave ت Maher
  • 1,561
  • 14
  • 8
  • 15
    Window should never be used as a workaround. It's the same as using globals. Highly discouraged, bad practice that leads to more long-term issues than it solves. – MarcinWolny Oct 16 '20 at 12:11
  • see this answer also https://stackoverflow.com/questions/71712011/global-window-object-element-implicitly-has-an-any-type-because-index-express – mattsmith5 Apr 02 '22 at 17:57
50

I was actually working with React and I got this error when I assigned an object's property through a custom key (i.e. myObj[myKey] = ). To resolve it, I simply used as keyof:

interface IMyObj { title: string; content: string; }
const myObj: IMyObj = { title: 'Hi', content: 'Hope all is well' };
const myKey: string = 'content';

myObj[myKey as keyof IMyObj] = 'All is great now!';

This explicitly tells Typescript that your custom string (myKey) belongs to the group of properties from an interface/type you used for declaring your object (myObj).

P.S.: another way to get the property's value is shown on a closed Typescript's issue on Github through extends:

interface IMyObj {
  title: string;
  content: string;
}

const myObj: IMyObj = { title: 'Hi', content: 'Hope all is well' };
const myKey: string = 'content';

const getKeyValue = <T extends object, U extends keyof T>(obj: T) => (key: U) =>
  obj[key];
console.log(getKeyValue(myObj)(myKey));
CPHPython
  • 12,379
  • 5
  • 59
  • 71
  • If it worked at one time, it no longer seems to with Typescript 4.7.4 TS2345: Argument of type 'string' is not assignable to parameter of type 'keyof IMyObj'. – oravecz Jul 15 '22 at 14:39
  • @oravecz [typescriptlang.org/play (code above run in the online compiler)](https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgJIFkCeB5ARgK2QG9kxgwAbCALmQGcwpQBzAbmQQHtwJxaGmINsgC+AKC4gGyALY4CtDPMIBeYqXJVaAcgASwbQBoO3SH2R7OABxRwKFZMDrIA7hHvbRrCd2lyA0hCY-IwsyGrakmZg2t5icnj4ANoBQchwzgDWQZwwaFiJALrhFgCC9o7OzFAQcGDIIJwuAISxQA) no errors are shown, both in _v4.7.4_ and _v4.8.0-beta_. `console.log(myKey as keyof IMyObj)` outputs "content". – CPHPython Jul 20 '22 at 17:16
7

In tsconfig.json

 compilerOptions:{

  "suppressImplicitAnyIndexErrors": true,
  "strictNullChecks":false,
  "strictPropertyInitialization": false,

 }
rohit.khurmi095
  • 2,203
  • 1
  • 14
  • 12
  • 31
    Just changing `tsconfig.json` settings is not a real answer. Perhaps a comment. These settings can be manipulated to do away with any/all TS errors. – CodeFinity Dec 12 '21 at 17:09