Reputation: 7260
The following code block returns a TypeScript error.
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ id: string; path: string; basename: string; createdOn: string; modifiedOn: string; content: string; }'.
Square brackets work fine in JavaScript (or using //@ts-ignore
).
What is the right way of doing this in TypeScript?
export interface Data {
[key: string]: {
id: string
path: string
basename: string
createdOn: string
modifiedOn: string
content: string
}
}
const data = _data as Data // _data is JSON
for (let item in data) {
for (let property in data[item]) {
console.log(property)
if (["createdOn", "modifiedOn"].includes(property)) {
data[item][property] = new Date(data[item][property])
}
}
}
Here’s what the JSON of _data
looks like.
{
"readme": {
"id": "3905d7917f2b3429490b01cfb60d8f5b",
"path": "README.md",
"basename": "README.md",
"createdOn": "2020-02-26T12:29:26.181Z",
"modifiedOn": "2020-02-26T12:29:26.181Z",
"content": "<!--\nTitle: Privacy guides\nDescription: Privacy guides will be published shortly...\n-->\n\n# Privacy guides\n\nPrivacy guides will be published shortly...\n"
},
...
}
Upvotes: 1
Views: 1558
Reputation: 66113
The reason is two fold:
property
has a string
type, instead of being known as a key in the nested objectdata[item][property] = new Date(...)
will return an error anyway, because your nested object only expect string as valuesSince using .includes()
or .indexOf()
does not narrow the type properly, you will have to create a function that basically returns the correct keys. This serves as a type guard that will return the correct types from a union type:
function hasPossibleDateAsValue(value: string): value is 'createdOn' | 'modifiedOn' {
return ["createdOn", "modifiedOn"].includes(value);
}
Then, you can do this without TypeScript throwing an error/warning:
for (let item in data) {
for (let property in data[item]) {
if (hasPossibleDateAsValue(property)) {
data[item][property] = new Date(data[item][property]);
}
}
}
See proof-of-concept on TypeScript playround.
Upvotes: 2