Общая функция сортировки - PullRequest
0 голосов
/ 17 октября 2019

Я пытаюсь превратить функцию сортировки пользовательского интерфейса материала в общий типизированный. Так что я могу использовать его с любым видом стола. Я застрял при использовании функции stableSort, которая использует функцию getSorting.

stableSort:

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);

getSorting:

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, но это универсальный тип, и их значения не будут одинаковыми. Небольшая репликация этой проблемы на игровой площадке

  2. У меня ошибка компиляции при вызове функции stableSort. ( Решено , проверьте мой ответ ниже)

Вот ссылка на игровую площадку

Ответы [ 2 ]

0 голосов
/ 18 октября 2019

Проблема первая может быть решена, это было

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, но не обязательно, напечатав его таким образом

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

Теперь вы говорите, что P является либо keyof внешним props, либо строкой. Очевидно, вы можете заменить строку любыми другими значениями, которые у вас там могут быть.

0 голосов
/ 17 октября 2019

Хорошо, я выяснил, что печатать для 2 и проблемы. Но сейчас я могу использовать хакерский способ игнорировать проблему 1 st и двигаться дальше. Который просто использует props.defaultOrderBy as string

Вот решение 1-й проблемы и игнорирует 2-ю

Если у кого-то есть лучшее решение, пожалуйста, поделитесь им со мной.

...