Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I prevent the error "Index signature of object type implicitly has an 'any' type" when compiling typescript with noImplicitAny flag enabled?

Tags:

typescript

I always compile Typescript with the flag --noImplicitAny. This makes sense as I want my type checking to be as tight as possible.

My problem is that with the following code I get the error Index signature of object type implicitly has an 'any' type:

interface ISomeObject {     firstKey:   string;     secondKey:  string;     thirdKey:   string; }  let someObject: ISomeObject = {     firstKey:   'firstValue',     secondKey:  'secondValue',     thirdKey:   'thirdValue' };  let key: string = 'secondKey';  let secondValue: string = someObject[key]; 

Important to note is that the idea is that the key variable comes from somewhere else in the application and can be any of the keys in the object.

I've tried explicitly casting the type by:

let secondValue: string = <string>someObject[key]; 

Or is my scenario just not possible with --noImplicitAny?

like image 617
Jasper Schulte Avatar asked Oct 06 '15 11:10

Jasper Schulte


People also ask

Which type string has no matching index signature?

The error "No index signature with a parameter of type 'string' was found on type" occurs when we use a value of type string to index an object with specific keys. To solve the error, type the string as one of the object's keys using keyof typeof obj .

What is an index signature typescript?

The index signature is a fitting way to handle objects with properties we know nothing about. Its syntax describes a regular property, but instead of writing a standard property name, we define the type of keys and the properties.

Is incompatible with index signature?

The error "Property is incompatible with index signature" occurs when a property is not compatible with the specified type of the index signature. To solve the error, change the type of the property or use a union to update the type in the index signature.

Has an any type because index expression is not of type number?

The error "Element implicitly has 'any' type because index expression is not of type 'number'" occurs when an array is indexed with a value that is not a number. To solve the error, use an object if storing key-value pairs or use a type assertion.


2 Answers

Adding an index signature will let TypeScript know what the type should be.

In your case that would be [key: string]: string;

interface ISomeObject {     firstKey:      string;     secondKey:     string;     thirdKey:      string;     [key: string]: string; } 

However, this also enforces all of the property types to match the index signature. Since all of the properties are a string it works.

While index signatures are a powerful way to describe the array and 'dictionary' pattern, they also enforce that all properties match their return type.

Edit:

If the types don't match, a union type can be used [key: string]: string|IOtherObject;

With union types, it's better if you let TypeScript infer the type instead of defining it.

// Type of `secondValue` is `string|IOtherObject` let secondValue = someObject[key]; // Type of `foo` is `string` let foo = secondValue + ''; 

Although that can get a little messy if you have a lot of different types in the index signatures. The alternative to that is to use any in the signature. [key: string]: any; Then you would need to cast the types like you did above.

like image 181
thoughtrepo Avatar answered Sep 20 '22 22:09

thoughtrepo


Another way to avoid the error is to use the cast like this:

let secondValue: string = (<any>someObject)[key]; (Note the parenthesis)

The only problem is that this isn't type-safe anymore, as you are casting to any. But you can always cast back to the correct type.

ps: I'm using typescript 1.7, not sure about previous versions.

like image 30
Pedro Villa Verde Avatar answered Sep 19 '22 22:09

Pedro Villa Verde