使用带有动态值的 LoDash orderBy 进行升序或降序排序

Use LoDash orderBy with dynamic values for ascending or descending sort

LoDash orderBy 函数非常简单 - 您将要排序的集合、要排序的属性传递给它,然后可选择对这些属性的排序是升序还是降序。典型用法可能如下所示:

let sortedCollection = _.orderBy(unsortedCollection, ['columnA', 'columnB'], ['asc', 'desc']);

我需要能够动态设置排序依据的属性,以及每个属性的排序应该是升序还是降序。我在动态设置要排序的属性时没有遇到任何问题,但我不知道如何动态设置 ascending/descending 选项。我有一个带有 nameorder 属性 的 SortOrderItem 对象。如果 ordertrue 那么 属性 应该升序排序,否则降序。

namespace app.models {
    export class SortOrderItem {
        name: string;
        order: boolean;
    }
}

我有一个数组(存储在一个名为 sortOrder 的数组中),在 UI 中设置,当我想对我的集合进行排序时,我循环遍历数组以构建属性和(希望)排序顺序:

private getSortedRecords(unsortedCollection: any[]): any[] {
    let sortColumns: string[] = [];
    let sortOrders: string[] = [];
    _.forEach(this.sortOrder,
        (item: models.SortOrderItem) => {
            sortColumns.push(item.name);
            sortOrders.push(item.order ? 'asc' : 'desc');
        });
    return _.orderBy(unsortedCollection, sortColumns, sortOrders);
}

但是,这不起作用,因为它不喜欢第三个参数的字符串数组。我得到:

TS2769: (TS) No overload matches this call.
 The last overload gave the following error.
  Argument of type 'string[]' is not assignable to a parameter of type 'Many <boolean | "asc" | "desc">'.
   Type 'string[]' is not assignable to type 'readonly (boolean | "asc" | "desc")[]'.
    Type 'string' is not assignable to type 'boolean | "asc" | "desc"'.

然后我尝试使用 readonly(boolean|'asc'|'desc')[] 作为我的 sortOrders 变量的类型:

let sortOrders: readonly(boolean|'asc'|'desc')[] = [];

这不起作用,因为我得到了这个错误:

TS2339: (TS) Property 'push' does not exist on type 'readonly (boolean|"asc"|"desc")[]'.

我该如何设置才能动态定义最后一个参数?

定义一个SortOrder类型:

type SortOrder = 'asc' | 'desc';

并将其用作sortOrders的类型:

function getSortedRecords(unsortedCollection: any[]): any[] {
  const sortColumns: string[] = [];
  const sortOrders: SortOrder[] = [];
  _.forEach(this.sortOrder,
      (item: SortOrderItem) => {
          sortColumns.push(item.name);
          sortOrders.push(item.order ? 'asc' : 'desc');
      });
  return _.orderBy(unsortedCollection, sortColumns, sortOrders);
}