Как создать литеральный объект из массива, объединенного в объект в Typescript?

#typescript

#typescript

Вопрос:

Я остановился на следующем фрагменте кода в Typescript:

 type SortedList = T[] amp; {_brand: "sorted" };

function binarySearch<T>(xs: SortedList<T>, x: T): boolean 
      let low = 0;
      let high = xs.length - 1;

      while (high >= low) {
          const mid = low   Math.floor((high - low) / 2);
          const v = xs[mid];
          if (v === x) {
              return true;
          }
          [low, high] = x > v ? [mid   1, high] : [low, mid - 1];
      }
  return false;
}
  

Мне интересно, как я мог бы создать литеральный объект типа SortedList?

Ответ №1:

Один из вариантов:

 const sortedList: SortedList<string> = Object.assign(["test"], { _brand: "sorted" } as const)
  

Если вы не хотите снижения производительности, вызванного Object.assign , вы также можете создать служебный метод, который выполняет приведение типов:

 function sorted<T>(_arr: T[]) {
    const arr = _arr as SortedList<T>
    arr._brand = "sorted"
    return arr
}
const sortedList: SortedList<string> = sorted(["test"])
  

Ответ №2:

Основываясь на ответе @Rubydesic с Object.assign , он, вероятно, предназначен для использования примерно так:

 // never manually create a `SortedList` - only create using this function
function sortList<T>(list: T[], sortFn?: (a: T, b: T) => number): SortedList<T> {
  return Object.assign([...list].sort(sortFn), { _brand: "sorted" } as const);
}

const list = [3, 4, 1, 5, 7];
const sorted = sortList(list);

// this ensures type safety against potential problems like this
// (attempting to binary search an unsorted list)
binarySearch(list, 3); // Argument of type 'number[]' is not assignable to parameter of type 'SortedList<number>'.

// ...while still allowing this
binarySearch(sorted, 3); // OK
  

Игровая площадка