使用Array和TypedArray重载Typescript中的递归函数

时间:2018-11-14 14:19:58

标签: typescript generics recursion overloading

我有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 []'不能分配给'(number | T)[]'类型的参数。

首先,我不太明白为什么打字稿会尝试将参数array的类型与不同签名中不存在的类型(number | T)[]进行比较。是否尝试将array的类型与comp函数的参数类型进行比较?

当然,我可以在实现签名中用array替换参数any的类型,它可以工作,但是我想知道是否有更好的方法来处理这种情况。 / p>

1 个答案:

答案 0 :(得分:0)

问题是实现重载(即最后一个)不能直接调用,因此当您递归调用函数时,类型必须与两个重载之一兼容,并且联合与任何一个都不兼容(打字稿不会尝试结合签名以允许传递联合)

在这种情况下,最简单的解决方案是复制实现签名:

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
}

另一种解决方案是使用一种更通用的类型,并且适用于两种类型的数组,如注释中所建议。