Reputation: 904
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:
Upvotes: 12
Views: 30236
Reputation: 31
You should cast the result of Object.keys(DATA)
to (keyof typeof DATA)[]
since Object.keys
by default returns string[]
.
const DATA = {
name: "John",
surname: "Smith",
gender: "Male"
}
const keys = Object.keys(DATA) as (keyof typeof DATA)[];
const result = keys.map((d) => `${d} - ${DATA[d]}`);
Also, make sure you don't cast the iterating variable d
to string
. By not casting it to string
, its type will be automatically inferred.
Upvotes: 0
Reputation: 24114
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...
Record
typeconst DataRecord: Record<string, string> = {
name: "Johnny-come-lately",
surname: "Smithers",
gender: "Male"
}
for (const key of Object.keys(DataRecord)) {
console.log(`${key}: ${DataRecord[key]}`);
}
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]}`);
}
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}`));
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]}`);
}
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]}`);
}
Upvotes: 20
Reputation: 10025
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]}`)
Upvotes: 9
Reputation: 252
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"
}
Upvotes: 0
Reputation: 6505
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]}`)
Upvotes: 2