使用Math.min.应用于Float32Array



我在将JS文件转换为TS时遇到了以下问题,示例与下面的代码类似:

let arr = Float32Array(3)
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;

let min_value = Math.min.apply(null, arr);

在本例中,TypeScript将产生一个错误,并显示以下消息:

Argument of type 'Float32Array' is not assignable to parameter of type 'number[]'.
Type 'Float32Array' is missing the following properties from type 'number[]': pop, push, concat, shift, and 5 more.

假设arr是性能敏感的变量,不应该转换为number[],欺骗编译器工作的最明显的解决方案是转换变量:

let min_value = Math.min.apply(null, arr as unknown as number[]);

在这种情况下,apply不能接收Float32Array参数的具体原因/危险性是否存在?

Function.protype.apply((声明arguments参数可以是任何类似数组的对象。

Typed数组是类似数组的对象,因此它们应该被apply方法接受。

此外,Math.min规范指出,它的参数甚至不需要是数字:

给定零个或多个参数,此函数会对每个参数调用ToNumber,并返回最小的结果值。

了解了以上所有内容,您尝试做的事情看起来是正确的,而且看起来像是TypeScript错误。

至于为什么会发生这种情况,目前Math.minCallableFunction.apply的定义如下:

min(...values: number[]): number;
apply<T, A extends any[], R>(
this: (this: T, ...args: A) => R,
thisArg: T,
args: A
): R;

很可能这两个定义都需要根据标准进行调整

编辑:可能只有apply定义需要更改为类似的内容

apply<T, A extends Iterable<AT>, AT, R>(
this: (this: T, ...args: AT[]) => R,
thisArg: T,
args: A
): R;

或者更准确地说,应该使用ArrayLike<AT>而不是Iterable<AT>,但为了使上述功能发挥作用,ArrayLike需要从Iterable扩展

TypeScript安全的编写方法是:

let min_value = Math.min(...arr);

其编译为Math.min.apply(Math, arr);

最新更新