'TypeScript map over Object keys and values: Element implicitly has an 'any' type
I am trying to iterate over object keys and values but TypeScript is shouting at me that:
Element implicitly has an
any
type because of typestring
can't be used to index type{ name: string; surname: string; gender: string; }
What am I doing wrong?
const DATA = {
name: "John",
surname: "Smith",
gender: "Male"
}
const result = Object.keys(DATA).map((d: string) => `${d} - ${DATA[d]}`)
Here is a screenshot of the error:
Solution 1:[1]
Just cast the string returned from the Object.keys into the key of the Data object.
const DATA = {
name: "John",
surname: "Smith",
gender: "Male"
}
const result = Object.keys(DATA).map((d: string) => `${d} - ${DATA[d as keyof typeof DATA]}`)
Solution 2:[2]
Error
Element implicitly has an
any
type because expression of typestring
can't be used to index type{name: string; surname: string; gender: string; }
.
No index signature with a parameter of typestring
was found on type...
Solution 1: Define object as Record
type
const DataRecord: Record<string, string> = {
name: "Johnny-come-lately",
surname: "Smithers",
gender: "Male"
}
for (const key of Object.keys(DataRecord)) {
console.log(`${key}: ${DataRecord[key]}`);
}
Solution 2: Define object as an Indexable Type
const DataIndexableType: {[key: string]: string} = {
name: "Johnny-come-lately",
surname: "Smithers",
gender: "Male"
}
for (const key of Object.keys(DataIndexableType)) {
console.log(`${key}: ${DataIndexableType[key]}`);
}
Solution 3: Use Object.entries()
If for some reason it is not practical to add type information for the object, Object.entries()
may be used without using type casting.
const DATA = {
name: "John",
surname: "Smith",
gender: "Male"
}
// Object.entries
for (const [key, value] of Object.entries(DATA)) {
console.log(`${key}: ${value}`);
}
// Or Object.entries.map
Object.entries(DATA).map( ([key, value]) => console.log(`${key}: ${value}`));
Solution 4: Use a typecast on the keys
const DATA = {
name: "John",
surname: "Smith",
gender: "Male"
}
// Object.keys with typecast on key.
for (const key of Object.keys(DATA)) {
console.log(`${key}: ${DATA[key as keyof typeof DATA]}`);
}
Solution 5: Use a typecast on the object indicating indexability
const DATA = {
name: "John",
surname: "Smith",
gender: "Male"
}
// Object.keys with typecast on object.
for (const key of Object.keys(DATA)) {
console.log(`${key}: ${(DATA as {[key: string]: string})[key]}`);
}
Solution 3:[3]
You need to tell typescript that the keys of your object are of type string.
const DATA: {[key: string]: string} = {
name: "John",
surname: "Smith",
gender: "Male"
}
const result = Object.keys(DATA).map((d: string) => `${d} - ${DATA[d]}`)
Solution 4:[4]
The Object's keys themselves are not explicitly typed as strings.
When you do
Object.keys(DATA)
You're getting name, surname, gender as values to pass to map, not John, Smith, Male.
To type the keys as well you need to type the object like this:
type DataType = {[key:string]: string }
const DATA:DataType =
{
name: "John",
surname: "Smith",
gender: "Male"
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Christopher Peisert |
Solution 3 | Reyno |
Solution 4 | SJT |