I am building a react-native / typescript project and I run into this problem:
I have a list of objects that I fetch from an API, and it looks something like this:
[{ qwe1: 'Bob', qwe2: 18 },
{ qwe1: 'James', qwe2: 19 }]
But I don’t want to have those keys names for this object (qwe1, qwe2),
and I also don’t want to run throw all the objects and change all the keys.
So I thought to make an object that will hold all the keys of the original object but give nice access for better names for them, it’s look something like that :
{
name: 'qwe1',
age: 'qwe2'
}
and then when I want to access the user’s name for example I will do this:
myObject[objectKeyNames.name]
I also made a type for the object that look like this:
{qwe1: string; qwe2: number;}
But then an error was showed up saing that:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '<the name of the type>'
I am really new to typescript and I don’t really get this, I would be most grateful for your support.
Thanks in advance 🙂
2
Answers
Define your
objectKeyNames
object to specifically reference the keys from the data object.For example
Now Typescript knows that any key in
objectKeyNames
will reference a valid property name from the API result.As an aside, it’s usually trivial to re-map one data format to another
The whole point of TypeScript, as opposed to JavaScript, is type safety. In ordinary JavaScript,
person.lastMane
will silently give youundefined
; TypeScript compiler will give you a compile-time warning that people don’t have last manes. However, when you doperson[attribute]
, whereattribute
is a string whose value cannot be known at compile-time, TypeScript must wash hands of it. It can’t know ifattribute
will be"lastName"
, or if it will end up as"lastMane"
. So it goes "I don’t know about this, this is on you."In order to satisfy TypeScript, one thing you can do is have a lookup of accessors instead of a lookup of attribute names, so that you never need to dynamically look up an attribute by a string. Something like this:
EDIT: …but Phil’s solution is smarter 🙂 I leave this up primarily because of the explanation of why you are getting the error.