Перегрузка рекурсивной функции в Typescript с помощью Array и TypedArray - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть рекурсивная функция с 2 перегрузками:

export function select(
  array: Float32Array,
  first: number,
  nth: number,
  last: number,
  comp: (a: number, b: number) => boolean,
): void;
export function select<T>(
  array: T[],
  first: number,
  nth: number,
  last: number,
  comp: (a: T, b: T) => boolean,
): void;
export function select<T>(
  array: Float32Array | T[],
  first: number,
  nth: number,
  last: number,
  comp: (a: number | T, b: number | T) => boolean,
): void {
  // Implementation of Floyd-Rivest algorithm
  // Some code
  select(array, newFirst, nth, newLast, comp);
  // Some code
}

Typescript жалуется на переменную array при рекурсивном вызове функции select в реализации:

Аргумент типа 'Float32Array | T [] 'нельзя назначить параметру типа' (число | T) [] '.

Во-первых, я не очень понимаю, почему машинопись пытается сравнить тип аргумента array с типом (number | T)[], которого нет в разных сигнатурах. Пытается ли сравнить тип array с типом аргументов функции comp?

Конечно, я могу заменить тип аргумента array на any в сигнатуре реализации, это работает, но я хотел бы знать, есть ли лучший способ обработать этот случай.

1 Ответ

0 голосов
/ 14 ноября 2018

Проблема в том, что перегрузка реализации (т. Е. Последняя) не вызывается напрямую, поэтому при рекурсивном вызове функции типы должны быть совместимы с одной из двух перегрузок, а объединение несовместимо с(машинопись не будет пытаться объединить подписи, чтобы разрешить передачу профсоюзов)

Самое простое решение в такой ситуации - дублировать сигнатуру реализации:

export function select(
    array: Float32Array,
    first: number,
    nth: number,
    last: number,
    comp: (a: number, b: number) => boolean,
): void;
export function select<T>(
    array: T[],
    first: number,
    nth: number,
    last: number,
    comp: (a: T, b: T) => boolean,
): void;
export function select<T>(
    array: Float32Array | T[],
    first: number,
    nth: number,
    last: number,
    comp: (a: number | T, b: number | T) => boolean,
): void;
export function select<T>(
    array: Float32Array | T[],
    first: number,
    nth: number,
    last: number,
    comp: (a: number | T, b: number | T) => boolean,
): void {
    // Implementation of Floyd-Rivest algorithm
    // Some code
    let newFirst = 0
    let newLast = 0
    select(array, newFirst, nth, newLast, comp);
    // Some code
}

Другое решение будетиспользовать тип, который является более общим и применимым для обоих типов массивов, как предлагается в комментариях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...