I have a database model interface User
. I want to fetch all users and store them in a key-value pair with groupBy()
from lodash like this:
const users: {[_id: string]: User} = _.groupBy(await db.Users.find(), '_id');
// users = {'x': {_id: 'x', name: 'Rifat'}, 'y': {_id: 'y', name: 'Reza'}}
This is giving me this error Type 'Dictionary<(Document<unknown, any, User> & Omit<User & Required<{ _id: string; }>, never>)[]>' is not assignable to type '{ [_id: string]: User; }'. 'string' index signatures are incompatible.
Eventually I want to be able to do something like this:
const user = users['x']; // which should treat user as User
Loadash's groupBy
returns an object where each property is an array of the items that share the group key.
So:
const things = [{ name: 'foo', tag: 'a' }, { name: 'bar', tag: 'a' }]
const grouped = _.groupBy(thing => thing.tag)
// { 'a': [{ name: 'foo', tag: 'a' }, { name: 'bar', tag: 'a' }] }
Which means you need your type to be { [_id: string]: User[] }
(note the []
to make that an array).
With that one addition, your code works just fine:
const users: { [_id: string]: User[] } = _.groupBy(await db.Users.find(), '_id');
But, considering this is a list of users from a database, they probably all have a unique _id
. Which means you probably don't want the groupBy
method at all, because you do not want groups of users. You probably want keyBy
instead, which returns an object where some property each array member becomes a key in the returned object.
So if you change it to keyBy
then your original type works just fine:
const users: { [_id: string]: User } = _.keyBy(await db.Users.find(), '_id');
Lastly, you probably don't even need an explicit type here. You let Typescript infer the type of users
from usage, and it will also just work fine.
const users = _.keyBy(await db.Users.find(), '_id');
const user = users['x'] // type: User