通用排序函数

Generic sorting function

我正在尝试将 material UI 排序函数转换为通用类型。这样我就可以将它与任何类型的 table 一起使用。我坚持使用 stableSort 函数,它使用 getSorting 函数。

stable排序:

const getSorting = <K extends keyof any>(
    order: Order,
    orderBy: K,
): (a: { [key in K]: number | string }, b: { [key in K]: number | string }) => number =>
    order === "desc" ? (a, b) => desc(a, b, orderBy) : (a, b) => -desc(a, b, orderBy);

获取排序:

const stableSort = <T>(array: T[], cmp: (a: T, b: T) => number): T[] => {
    const stabilizedThis = array.map((el, index) => [el, index] as [T, number]);
    stabilizedThis.sort((a, b) => {
        const order = cmp(a[0], b[0]);
        if (order !== 0) return order;
        return a[1] - b[1];
    });
    return stabilizedThis.map((el) => el[0]);
};

这就是我使用函数的方式,

interface ITableProps<T> {
    title: string;
    rows: T[];
    defaultOrderBy: keyof T;
    order: Order;
}

const SomeTable = <T>(props: ITableProps<T>) => {
    const rowsPerPage = 10;
    const page = 0;

    const handleRequestSort = <T>(property: keyof T): void => {
        const isDesc = props.defaultOrderBy === property && props.order === "desc";
    };

    const sortingFunction = getSorting<keyof T>(props.order, props.defaultOrderBy);

    const temp = stableSort<T>(props.rows, sortingFunction)
                    .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                    .map((row, index) => createTableRow(row, index))
}

我面临几个问题,

  1. 我不明白为什么它认为 props.defaultOrderBy === property 永远是 false。我知道两者都是 keyof T,但那是泛型,它们的值不会相同。 Small contained replication of this problem in playground

  2. 调用stableSort函数时出现编译错误。 (已解决,检查下面我的回答)

Here is the playground link

好的,我想出了 2 第二个问题的输入法。但现在我可以使用一种 hacky 的方式来忽略 1st 问题,然后继续前进。这只是使用 props.defaultOrderBy as string

Here is the solution to the 1st problem and ignores the 2nd

如果有人有更好的解决方案,请与我分享。

问题一可以解决这是

interface ISomeComponentProps<T> {
    firstValue: keyof T;
    secondValue: keyof T;
}

const SomeComponent = <T>(props: ISomeComponentProps<T>): void => {
    const someFunction = <P>(property: keyof T): boolean => {
        return props.firstValue === property;
    };

    const temp = someFunction(props.secondValue);
}

在您之前的代码中,您使用的是 someFunction = <T>(property: keyof T) 这会导致打字稿失去对外部泛型 T 的引用,因为它们是相同的泛型变量。通过将内部函数切换为 <P>(property: keyof T) 我们说内部是一个通用函数,它必须将外部函数的一个键作为其 属性 。这是确保重叠的唯一方法是键入它,以便必须有重叠。

你也可以这样输入告诉TS它可能是T的key但不一定是

const someFunction = <P>(property: keyof T | string): boolean => ...

现在你说 P 是一个 keyof 外面的 props 或者一个字符串。显然,您可以将字符串替换为您可能拥有的任何其他值。