177

this is part of my code:

const myObj: object = {}
const propname = 'propname'

myObj[propname] = 'string'

but I got error:

ERROR in path/to/file.ts(4,1)
TS7053: Element implicitly has an 'any' type because expression of type '"propname"' can't be used to index type '{}'.
  Property 'propname' does not exist on type '{}'.

What is wrong here, and how can I fix it?

Cichy
  • 4,602
  • 3
  • 23
  • 28
  • 1
    Duplicate of https://stackoverflow.com/questions/12710905/how-do-i-dynamically-assign-properties-to-an-object-in-typescript – TSR Jul 01 '19 at 10:07

8 Answers8

293

You have to define what kind of index type the object has. In your case it is a string based index.

const myObj: {[index: string]:any} = {}
Murat Karagöz
  • 35,401
  • 16
  • 78
  • 107
43

Below are a few solutions to solve the "TS7053 Element implicitly has an 'any' type" error when accessing properties via array-access.

Original code:

const myObj: object = {}
const prop = 'propname'
myObj[prop] = 'string'  // Error!

Note: This does not work because the index-signature is still undefined:

const myObj: {propname: any} = {}
const prop = 'propname'
myObj[prop] = 'string'  // Error!

Solution 1: Implicit define the index signature

const myObj: {[key: string]: any} = {}
const prop = 'propname'
myObj[prop] = 'string'

Solution 2: Use an interface to provide the index signature

interface IStringIndex {
    [key: string]: any
}

const myObj: IStringIndex = {}
const prop = 'propname'
myObj[prop] = 'string'

Solution 3: Use an interface and extend the <Record> utility type:

interface IStringIndex extends Record<string, any> {}

const myObj: IStringIndex = {}
const prop = 'propname'
myObj[prop] = 'string'

Solution 4: Define a type alias with the index signature

type MyObject = {
    [key: string]: any
    propname?: any
}

const myObj: MyObject = {}
const prop = 'propname'
myObj[prop] = 'string'

Solution 5: Combination of an interface to describe the index-signature and a type alias to describe valid properties:

interface IStringIndex extends Record<string, any> {}
type MyObject = IStringIndex & {
    propname?: string
}

const myObj: MyObject = {}
const prop = 'propname'
myObj[prop] = 'string'

Solution 6: Define a list of valid (string) property names:

type ValidProps = 'propname' | 'value'
interface IStringIndex extends Record<ValidProps, any> {}

const myObj: IStringIndex = {
    propname: 'my prop',
    value: 123
}
const prop = 'propname'
myObj[prop] = 'string'

Note: All properties from the ValidProps list must be present when assigning the object!

Philipp
  • 10,240
  • 8
  • 59
  • 71
20

In case you have an interface / class defined and it still throws that error, you could use keyof as follows:

interface SomeInterface {
  propertyA: string;
  propertyB: string;
}

const object: SomeInterface = {propertyA: 'A', propertyB: 'B'};

for ( const prop in object ) {
  const value = object[prop]; // <-- will throw an error
  const typedValue = object[prop as keyof SomeInterface]; // <-- will do fine
}

Otherwise you could "hack" it by adding generic property to that interface / class which would go through, but it opens quite a different door for type unsafety :)

interface SomeInterface {
  propertyA: string;
  propertyB: string;
  [key: string]: any;
}
pop
  • 3,464
  • 3
  • 26
  • 43
6

Go to the: tsconfig.json, and set the below options

"compilerOptions": {
        "noImplicitAny": false,
}

const listOfArray: Array<any> = [];
for(const Id in MyObject)
{
   listOfArray.push(dataList[Id]);//TS7053 Error here -- Fixed by doing above things
}

Facing the same error when I tried to Push the result which comes from MyObject [{Id: value 1},{Id: 2},{Id: 3}].

ouflak
  • 2,458
  • 10
  • 44
  • 49
Maulik Boghara
  • 129
  • 1
  • 5
4

const myObj: object = {'foo': 'bar'}

const propname = 'foo';

(myObj as any)[propname] = 'baz';
Heitor Giacomini
  • 384
  • 2
  • 12
2

Create TS Map intead.

const myObj = new Map();
myObj.set('propname', "something");

const propname = 'propname'
myObj.get(propname)
Shubham Prakash
  • 363
  • 1
  • 4
  • 3
2

use suppressImplicitAnyIndexErrors tsconfig. detail doc about this config: https://www.typescriptlang.org/tsconfig#suppressImplicitAnyIndexErrors

baihaihui
  • 153
  • 1
  • 7
0

I had a problem with JSON objects. The "type" key is used in the switch statement and case options are strings.

In older versions of Ionic was enough:

var jsonMessage: JSON;

In newer versions I had to use:

var jsonMessage: {"type": string, "data": string};

or

var jsonMessage: {"type": any, "data": any};
Wlado87
  • 1
  • 1