Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript error: TS7053 Element implicitly has an 'any' type

Tags:

typescript

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?

like image 673
Cichy Avatar asked Jul 01 '19 09:07

Cichy


People also ask

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.

Has an any type because expression of type string can't be used to index type?

The error "Element implicitly has an 'any' type because expression of type 'string' can't be used to index type" occurs when we use a string to index an object with specific keys. To solve the error, type the string as one of the object's keys.


2 Answers

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} = {}
like image 64
Murat Karagöz Avatar answered Oct 11 '22 09:10

Murat Karagöz


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!

like image 20
Philipp Avatar answered Oct 11 '22 08:10

Philipp