Repository: toss/es-toolkit
File: src/compat/array/orderBy.ts (TypeScript)

Code before:
  const getValueByCriterion = (
    criterion: PropertyKey | ((item: T) => unknown) | PropertyKey[] | { key: PropertyKey; path: string[] },
    object: T
  ) => {
    if (object == null) {
      return object;
    }

    if (typeof criterion === 'function') {
      return criterion(object);
    }

    if (Array.isArray(criterion)) {
      return getVaueByNestedPath(object, criterion);
    }

    if (typeof criterion !== 'object') {
      return object[criterion as keyof typeof object];
    }

    // Case for possible to be a deep path
    if (Object.hasOwn(object, criterion.key)) {
      return object[criterion.key as keyof typeof object];
    }

    return getVaueByNestedPath(object, criterion.path);
  };

  // Prepare all cases for criteria
  const preparedCriteria = criteria.map(criterion => {
    // lodash handles a array with one element as a single criterion
    if (Array.isArray(criterion) && criterion.length === 1) {
      criterion = criterion[0];
    }

    if (typeof criterion === 'function' || Array.isArray(criterion) || isKey(criterion)) {
      return criterion;
    }

    // If criterion is not key, it has possibility to be a deep path. So we have to prepare both cases.
    return { key: criterion, path: toPath(criterion as string) } as const;
  });

  return (collection as T[]).slice().sort((a, b) => {
    for (let i = 0; i < criteria.length; i++) {
      const order = String((orders as unknown[])[i]); // For Object('desc') case
      const valueA = getValueByCriterion(preparedCriteria[i], a);
      const valueB = getValueByCriterion(preparedCriteria[i], b);

      const comparedResult = compareValues(valueA, valueB, order);


Review comment (suggestion):
```suggestion
    return getValueByNestedPath(object, criterion.path);
```

Code after:
  const getValueByCriterion = (
    criterion: PropertyKey | ((item: T) => unknown) | PropertyKey[] | { key: PropertyKey; path: string[] },
    object: T
  ) => {
    if (object == null) {
      return object;
    }

    if (typeof criterion === 'function') {
      return criterion(object);
    }

    if (Array.isArray(criterion)) {
      return getValueByNestedPath(object, criterion);
    }

    if (typeof criterion !== 'object') {
      return object[criterion as keyof typeof object];
    }

    // Case for possible to be a deep path
    if (Object.hasOwn(object, criterion.key)) {
      return object[criterion.key as keyof typeof object];
    }

    return getValueByNestedPath(object, criterion.path);
  };

  // Prepare all cases for criteria
  const preparedCriteria = criteria.map(criterion => {
    // lodash handles a array with one element as a single criterion
    if (Array.isArray(criterion) && criterion.length === 1) {
      criterion = criterion[0];
    }

    if (typeof criterion === 'function' || Array.isArray(criterion) || isKey(criterion)) {
      return criterion;
    }

    // If criterion is not key, it has possibility to be a deep path. So we have to prepare both cases.
    return { key: criterion, path: toPath(criterion as string) } as const;
  });

  return (collection as T[]).slice().sort((a, b) => {
    for (let i = 0; i < criteria.length; i++) {
      const order = String((orders as unknown[])[i]); // For Object('desc') case
      const valueA = getValueByCriterion(preparedCriteria[i], a);
      const valueB = getValueByCriterion(preparedCriteria[i], b);

      const comparedResult = compareValues(valueA, valueB, order);