Is there a way to make this code bellow more DRY or is this fine as it is? I am wondering if there could for instance be a way to combine the two functions in to 1, the output type of which would be determined by some typescript logic but I don't see how yet.
Please let me know if you happen to see anything else worth improving...
import { EntityManager, EntityTarget, In } from 'typeorm';
export async function batchEntitiesBy<Entity, T extends keyof Entity>(
em: EntityManager,
entityClass: EntityTarget<Entity>,
by: T,
variables: readonly Entity[T][]
): Promise<(Entity)[]> {
const entities = await em.find(entityClass, { [by]: In(variables as Entity[T][]) });
// reorder the entities to match by
const entityMap = new Map<Entity[T], Entity>()
entities.forEach((e) => {
entityMap.set(e[by], e)
})
return variables.map((v) => {
const out = entityMap.get(v)
if (!out) {
throw new Error(`Could not find ${entityClass} with ${String(by)} ${v}`)
}
return out
})
}
export async function batchEntitiesArrayBy<Entity, T extends keyof Entity>(
em: EntityManager,
entityClass: EntityTarget<Entity>,
by: T,
variables: readonly Entity[T][]
): Promise<Entity[][]> {
const entities = await em.find(entityClass, { [by]: In(variables as Entity[T][]) });
// reorder the entities to match by
const entityMap = new Map<Entity[T], Entity[]>()
entities.forEach((e) => {
const el = entityMap.get(e[by]) ?? []
el.push(e)
entityMap.set(e[by], el)
})
// ? do we need this []?
return variables.map((v) => {
const out = entityMap.get(v)
if (!out) {
throw new Error(`Could not find ${entityClass} with ${String(by)} ${v}`)
}
return out
})
}
```