Typescript: Convert an array of objects to object with ID as a key and correct typing
2 min readAug 31, 2023
If you have an array of objects like this
type A = {
id: '001' | '002'
value: unknown
}
const arr = [
{ id: '001', value: 'anything' },
{ id: '002', value: 'anything' },
]
And want to transform the arr
to this
const obj = {
'001': { id: '001', value: 'anything' },
'002': { id: '002', value: 'anything' },
}
The implementation shouldn’t be much of the problem because you can simply create a function that accepts (arr: T[], idKey: keyof T)
and use reduce()
or just do Object.fromEntries(arr.map(a => [a[idKey], a]))
then it should work at runtime
But how do we deal with the type of that function to make sure these 2 things in checked
- The
idKey
parameter should not be any key but only the keys that satisfy object’s key constraint (`string | number | symbol`) - The return type object’s keys need to be the value of that
idKey
parameter
This is one of the possible solutions
type AnyObject<TValue> = { [key: string]: TValue }
type StringKeys<T> = {
[K in keyof T]: T[K] extends string | number | symbol ? K : never;
}[keyof T];
const arrayToKeyObject =
<T extends Record<StringKeys<T>, string | number | symbol>, TKeyName extends keyof Record<StringKeys<T>, string | number | symbol>>(array: T[], key: TKeyName): Record<T[TKeyName], T> =>
Object.fromEntries(array.map(a => [a[key], a])) as Record<T[TKeyName], T>