Helpful TypeScript Generics

TS

1. Nested Keyof

type NestedKeyOf<ObjectType extends object> = {
  [Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object
    ? `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key]>}`
    : `${Key}`;
}[keyof ObjectType & (string | number)];

Uses

export default function groupBy<T extends object>(
  data: T[],
  groupByKey: NestedKeyOf<T>
) {
  const grouped = new Map<string, T[]>();

  for (const item of data) {
    const key = getObjectKey(item, groupByKey);
    const hasKey = grouped.has(key);
    if (!hasKey) {
      grouped.set(key, [item]);
      continue;
    }

    const prevContent = grouped.get(key);
    if (Array.isArray(prevContent)) {
      grouped.set(key, [...prevContent, item]);
    } else {
      grouped.set(key, [item]);
    }
  }
  return grouped;
}
const data = [
  {
    category: "JavaScript",
    title: "Closures in JavaScript",
    author: { name: "Elliot" },
  },
  {
    category: "JavaScript",
    title: "Debugging JavaScript",
    author: { name: "Jack" },
  },
  { category: "CSS", title: "Util classes", author: { name: "Elliot" } },
];

const grouped = groupBy(data, "author.name");