Although I have googled this error and seen many posts about the topic, I still couldn't figure out how to fix the error.
Straight to the example, I have data that looks like that:
const earthData = {
distanceFromSun: 149280000,
continents: {
asia: {area: 44579000, population: 4560667108},
africa: {area: 30370000, population: 1275920972},
europe: {area: 10180000, population: 746419440},
america: {area: 42549000, population: 964920000},
australia: {area: 7690000, population: 25925600},
antarctica: {area: 14200000, population: 5000}
}
}
I want to create a new object in which keys are continents names, and values are areas. I can easily do the following and it works well:
const outputWorks = Object.fromEntries(Object.entries(earthData.continents).map( ([k, o]) => [k, o.area] ))
// {
// "asia": 44579000,
// "africa": 30370000,
// "europe": 10180000,
// "america": 42549000,
// "australia": 7690000,
// "antarctica": 14200000
// }
By contrast, a very similar code doesn't work when the same input data is a result of a different operation.
const solarSystem = {
mercury: {},
venus: {},
earth: { // earth entry is just like `earthData` object
distanceFromSun: 149280000,
continents: {
asia: { area: 44579000, population: 4560667108 },
africa: { area: 30370000, population: 1275920972 },
europe: { area: 10180000, population: 746419440 },
america: { area: 42549000, population: 964920000 },
australia: { area: 7690000, population: 25925600 },
antarctica: { area: 14200000, population: 5000 },
},
},
mars: {},
jupiter: {},
saturn: {},
uranus: {},
neptun: {},
};
const earthDataExtracted = Object.values(solarSystem)[2] as any; // again, this is the same as `earthData`
So why does the following throw an error?
Object.fromEntries(Object.entries(earthDataExtracted.continents).map( ([k, o]) => [k, o.area] ))
// ^
(parameter) o: unknown
Object is of type 'unknown'.(2571)
And even more strangely, on my own machine (VSCode) the error is different:
Property 'area' does not exist on type 'unknown'.ts(2339)
Is there a simple thing I'm missing here?
anyinstead oftypeof earthData? Once you doObject.entries(x)wherexis of typeany, you're going to getArray<[string, unknown]>. For that matter, whyObject.entries(solarSystem)[2]instead ofsolarSystem.earth? The compiler has no idea what the former will be (it doesn't keep track of object property order) while the latter is easy.Object.entries(solarSystem)[2]and notsolarSystem.earthbecause the index (2) is figured out in a computation and I don't know it from the outset.Object.entries()you might as well store things in the array to begin with. But anyway, let's say you are handedearthDataExtractedand the compiler doesn't know what type it is (because all it knows is that it's some value). Then you should tell it the right type (e.g.,{ continents: Record<string, { area: number, population: number }> };) as opposed toanyif you want better behavior, like this, for example. Does that address your issue or am I missing something?areaandpopulation, and each of those other properties is likely to nest some more objects. So asserting the type as you suggest -- by laying out the entire data structure -- would be too painful.as typeof solarSystem.earthlike this but you don't know that it's at theearthkey. Surely somewhere in your code you have the types of the values you're dealing with, right? Is there nointerfaceor something that represents these things? Without a more evocative example I don't know how to propose an answer you'd accept.