Here is a simple utility function that converts an array to a keyed object using a custom attribute getter function to create a key. This can be useful when you need to transform an array of objects into an object where each key is derived from a specific attribute of the object.

/**
 * Converts an array to a keyed object using a custom attribute getter function.
 * @param array The array to convert.
 * @param attributeGetter The function to get the key from the item.
 */
function arrayToKeyedObject<T, K extends string>(
  array: T[],
  attributeGetter: (item: T) => K
) {
  if (!Array.isArray(array)) {
    throw new TypeError('First argument must be an array')
  }

  if (!attributeGetter || typeof attributeGetter !== 'function') {
    throw new TypeError('attributeGetter argument must me a function')
  }

  if (array.length === 0) {
    return {} as Record<K, T>
  }

  const map = {} as Record<K, T>

  for (const value of array) {
    const key = attributeGetter(value)
    map[key] = value
  }

  return map
}

Usage example

Here is an example of how you can use the arrayToKeyedObject function to convert an array of users into a keyed object where the key is the id of the user.

interface User {
  id: number
  name: string
}

const users: User[] = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
]


const usersById = arrayToKeyedObject(users, user => String(user.id))
console.log(usersById)
// Output: { '1': { id: 1, name: 'Alice' }, '2': { id: 2, name: 'Bob' }, '3': { id: 3, name: 'Charlie' } }

const getUserById = (id: string) => usersById[id]
console.log(getUserById('2'))
// Output: { id: 2, name: 'Bob' }