Reputation: 3299
I am new to typescript. I just trying to write some cloud functions for my firebase project. In that one requirement I have is to convert an array into an object. I am trying this technique to achieve that:
let msg = {
text : 'hi'
time : 123456789
}
let userIds = ['user1', 'user2']
let updateObj = userIds.reduce((obj, userId) => {
obj[userId + '/messages'] = msg
return obj
}, {})
What I want updateObj to be is:
{
'user1/messages' : {
'text' : 'hi'
'time' : 123456789
}
'user2/messages' : {
'text' : 'hi'
'time' : 123456789
}
}
But I don't to why it is giving me ths error:
src/index.ts:47:6 - error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
No index signature with a parameter of type 'string' was found on type '{}'.
47 obj[userId + '/messages'] = msg
Upvotes: 2
Views: 199
Reputation: 2329
You have multiple ways to solve this. The problem is that empty object doesn't accept arbitrary keys.
First option is to type the reduce function as Record<string, typeof msg>
which would allow you to assign the msg valuw under any key of that object. This would be the easiest and weakest (from the point of view of type safety) solution.
Other option would be to use template string literal as the key if you are using newer version of typescript and want to enforce that all of the keys are in that exact form of {string}\messages. To achieve that type the reduce as Record<``${string}\messages``, typeof msg>
.
Third option would be the most strongly typed where you can enforce the keys to be exactly as they are in the result by typying like Record<``${typeof userIds[number]}\messages``, typeof msg>
. For this to work you would also need to specify your userIds
with as const
so it's type will be ['user1', 'user2']
exactly and not string[]
.
These solutions apply exactly to your question so I guess in real code you don't have the users or msg static. So if users are an array of strings you get from api, 2nd option is best and if the msg object from the example can have different signatures just use the type of that or simply use unknown
if you want to allow any value.
Upvotes: 2