type PropertyKey
= (string | number | symbol)
= keyof any
const countBy = <T, TId extends PropertyKey>(
list: readonly T[],
identity: (item: T) => TId
): Record<TId, number> => {
if (!list) return {} as Record<TId, number>;
return list.reduce((acc, item) => {
const id = identity(item);
acc[id] = (acc[id] ?? 0) + 1;
return acc;
}, {} as Record<TId, number>);
};
countBy(colors, (color) => color);
// { red: 1, blue: 1, green: 1 }