And*_*rew 6 javascript typed-arrays typescript typescript-typings
我经常使用类型化数组,而且我的很多函数确实应该可以使用任何类型的类型化数组(例如,对a Uint8Array或a 求和Float32Array)。有时候,我只需要一个简单的类型并集就可以摆脱困境,但是我经常遇到相同的错误。
一个简单的例子:
type T1 = Uint8Array;
type T2 = Int8Array;
type T3 = Uint8Array | Int8Array;
// No problems here:
const f1 = (arr: T1) => arr.reduce((sum, value) => sum + value);
const f2 = (arr: T2) => arr.reduce((sum, value) => sum + value);
// Does not work:
const f3 = (arr: T3) => arr.reduce((sum, value) => sum + value);
Run Code Online (Sandbox Code Playgroud)
错误f3是:
Cannot invoke an expression whose type lacks a call signature. Type '
{
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number): number;
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue: number): number;
<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8Array) => U, initialValue: U): U;
} | {
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number;
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue: number): number;
<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U, initialValue: U): U;
}' has no compatible call signatures.ts(2349)
Run Code Online (Sandbox Code Playgroud)
根据文档:
如果我们拥有一个具有联合类型的值,则我们只能访问该联合中所有类型都通用的成员。
我在reduce这里使用的方式在所有数组中都是通用的,但是我想问题是可选的第4个参数(for Uint8Array.prototype.reduce是a Uint8Array但for Int8Array.prototype.reduce是an Int8Array)。
有一个简单的解决方法吗?或者我需要编写每一个泛型实现map,reduce,filter?
调用函数并集始终存在一个问题。直到最近,规则还不允许任何调用,但从 3.3 ( PR ) 开始,允许调用,但有一些警告。您在这里遇到的最大问题是,如果工会的成员都具有通用签名,则调用仍然不会被允许。例如,在简单数组上,forEach可以调用一个数组(上面没有泛型类型参数),而reduce不能调用一个数组(因为reducefromstring[]和 fromnumber[]都有一个泛型类型参数):
declare let o: string[] | number[];
o.forEach((e: number | string) => console.log(e)); // ok
o.reduce((e: number | string, r: number | string) => e + ' ' + r) //err
Run Code Online (Sandbox Code Playgroud)
这确实意味着数组类型的联合很难使用,并且只允许调用非常小的一组方法(大多数数组方法都有泛型类型参数)。
这也适用于Uint8Array和Int8Array虽然不继承数组但具有大多数相同方法的情况。
这里没有好的解决方案,最简单的解决方法是将变量断言为其中一种类型并使用它(假设您不使用回调array参数应该没问题)
const f3 = (arr: T3) => (arr as Uint8Array).reduce((sum, value, array /* no good inferred to Uint8Array */) => sum + value);
Run Code Online (Sandbox Code Playgroud)
或者退回到您可以调用的函数之一
const f4 = (arr: T3) => {
let sum = 0;
(arr as Uint8Array).forEach((val)=> sum + val)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
131 次 |
| 最近记录: |