SecurityYourFingers
@SecurityYourFingers
I make other things, but i know that without your

Typescript generic function. How use with other types?

/** 
Example array
*/
arr = [
  {
    name: 'John',
    author: 'Bender',
    year: 2003,
    text: [
        'Lorem ipsum',
        'Lorem ipsum',
        'Lorem ipsum'
      ]
  }
]

/** 
Example generic function

This function should sort array
*/

function sortArray<T extends [], K extends keyof T>  (originArr: T, propertyName: K, cb: (a: T) => T): T {
    
    let arr: T = JSON.parse(JSON.stringify(originArr));  //deep copy array
    let resultSort: T = arr;
    
    resultSort = arr.sort((a: K, b: K) => {

        let nameA = a[propertyName].toLowerCase(), nameB = b[propertyName].toLowerCase();

        if (nameA < nameB)
            return -1;
        if (nameA > nameB)
            return 1;
        return 0;
    });

    return cb(resultSort);
}


На данный момент я вижу проблему только в строке:
let nameA = a[propertyName].toLowerCase(), nameB = b[propertyName].toLowerCase();

a[propertyName] : Type 'K' cannot be used to index type 'K'.
b[propertyName] : Type 'K' cannot be used to index type 'K'.

Screen of IDE
5ed144c8643ed182280041.png
  • Вопрос задан
  • 223 просмотра
Решения вопроса 1
Aetae
@Aetae Куратор тега TypeScript
Тлен
Нет, проблем тут куча.

T extends [], K extends keyof T - K тут что-то производное от number, потому что ключи(keyof) массива([]) - только цифры.
let resultSort: T = arr; - бессмысленно, так как arr.sort в любом случае меняет исходный массив.
a[propertyName].toLowerCase() - упадёт если propertyName будет year, т.к. Number не имеет метода toLowerCase.
...

В итоге функция должна выглядеть как-то так:
function sortArray<T extends {[key: string]: unknown}, K extends keyof T>  (originArr: T[], propertyName: K, cb: (a: T[]) => T[]): T[] {
  let arr: T[] = JSON.parse(JSON.stringify(originArr));  //deep copy array

  arr.sort((a, b) => {
    let nameA = String(a[propertyName]).toLowerCase(),
        nameB = String(b[propertyName]).toLowerCase();

    if (nameA < nameB)
      return -1;
    if (nameA > nameB)
      return 1;
    return 0;
  });

  return cb(arr);
}


Можно не приводить строго к String, но тогда вместо unknown надо указать конкретные типы с которыми предполагается работать, и в самой функции сортировки их учесть.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@abberati
frontend-разработчик
Вместо T extends [] должно быть T extends T[]

И везде по коду массив — это не Т, а Т[]
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы