Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用数组和TypedArray重载Typescript中的递归函数_Typescript_Generics_Recursion_Overloading - Fatal编程技术网

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

使用数组和TypedArray重载Typescript中的递归函数,typescript,generics,recursion,overloading,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, la

我有一个带有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
}
导出功能选择(
数组:Float32Array,
第一:数字,
N:号码,
最后:号码,,
comp:(a:number,b:number)=>布尔值,
):无效;
导出功能选择(
数组:T[],
第一:数字,
N:号码,
最后:号码,,
comp:(a:T,b:T)=>布尔值,
):无效;
导出功能选择(
数组:Float32Array | T[],
第一:数字,
N:号码,
最后:号码,,
comp:(a:number | T,b:number | T)=>布尔值,
):无效{
//Floyd-Rivest算法的实现
//一些代码
选择(数组、新第一个、第n个、新最后一个、复合);
//一些代码
}
Typescript在实现中递归调用
select
函数时抱怨变量
array

类型为“Float32Array | T[]”的参数不能分配给类型为“(number | T)[]”的参数

首先,我真的不明白为什么typescript试图将参数
数组的类型与不同签名中不存在的类型
(number | t)[
进行比较。它是否尝试将
数组
的类型与
comp
函数的参数类型进行比较


当然,我可以在实现签名中用
任何
替换参数
数组
的类型,它是有效的,但我想知道是否有更好的方法来处理这种情况。

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

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

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
}
导出功能选择(
数组:Float32Array,
第一:数字,
N:号码,
最后:号码,,
comp:(a:number,b:number)=>布尔值,
):无效;
导出功能选择(
数组:T[],
第一:数字,
N:号码,
最后:号码,,
comp:(a:T,b:T)=>布尔值,
):无效;
导出功能选择(
数组:Float32Array | T[],
第一:数字,
N:号码,
最后:号码,,
comp:(a:number | T,b:number | T)=>布尔值,
):无效;
导出功能选择(
数组:Float32Array | T[],
第一:数字,
N:号码,
最后:号码,,
comp:(a:number | T,b:number | T)=>布尔值,
):无效{
//Floyd-Rivest算法的实现
//一些代码
设newFirst=0
设newLast=0
选择(数组、新第一个、第n个、新最后一个、复合);
//一些代码
}

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

如果将
T[]
更改为
ArrayLike
,该怎么办?由于还允许使用
Float32Array
,因此将不会使用任何数组原型函数。如果您也在for of循环中使用它,或者您可以添加
ArrayLike&Iterable
。谢谢,我不知道Typescript中的这些类型。Iterable似乎可以工作(因此不需要重载)。我不能使用ArrayLike,它看起来是只读的(数组在实现中是可变的)。添加联合签名基本上不符合重载的目的吗?不一定。。对于
floatarray
,第一个重载将处于活动状态,因此回调将使用
数字。对于其他
T[]
s,回调将采用
T
。只有当它是一个类型为
FloatArray | T[]
的并集时,才会触发最后一个重载。但是,似乎您基本上可以传递满足该并集的任何内容,并编译它,即使它可能是一个错误。。。像
select(floatArray,1,2,3,(a:string,b:string)=>a==b)
是允许的,因为它
floatArray
匹配
Float32Array
(string,string)=>boolean
匹配
(T,T)=>boolean
。。。即使它不再有意义。