如何将 array.prototype.reduce() 与 TypeScript 一起使用,同时将布尔累加器作为初始值?

Sha*_*hah 5 javascript reduce static types typescript

我打算在 binarysearch.io 上解决一些算法,并遇到了这个问题:

在此输入图像描述

我用JS解决了这个问题,如下:

class Solution {
    solve(nums) {
        const Hash = {};
        const Cache = {};
        
        for (let val of nums) {
            if (!Hash[val]) {
                Hash[val] = 0;
            }
            Hash[val]++; //implicit else
        }

        const result = Object.values(Hash).reduce((accum, curr) => {
            if (accum && Cache[curr] !== 'unique') {
                Cache[curr] = 'unique';
                return true
            }
            return false;
        }, true);
        
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,当我尝试用 TypeScript 解决这个问题时(我对 TypeScript 还很陌生),我遇到了可能由 .reduce() 方法引起的编译错误:

class Solution {
    solve(nums: Array<number>): boolean {
        const Hash = {};
        const Cache = {};
        
        for (let val of nums) {
            if (!Hash[val]) {
                Hash[val] = 0;
            }
            Hash[val]++; //implicit else
        }
        
        const val_arr = Object.values(Hash);

        return val_arr.reduce((accum, curr) => {
            if (accum && Cache[curr] !== 'unique') {
                Cache[curr] = 'unique';
                return true;
            }
            return false;
        }, true);
    }
}
Run Code Online (Sandbox Code Playgroud)

我不确定如何为 .reduce() 方法提供种子初始值的返回类型。我尝试将初始值更改为布尔类型,但仍然出现编译错误:

return val_arr.reduce((accum, curr) => {
            if (accum && Cache[curr] !== 'unique') {
                Cache[curr] = 'unique';
                return true;
            }
            return false;
        }, true as boolean);
Run Code Online (Sandbox Code Playgroud)

我尝试搜索其他人是否有这个问题,但我发现的大多数帖子都以对象作为初始值,所以我不太明白。看起来最简单的解决方案是解决这个问题,即在不使用 .reduce() 的情况下重构来解决这个问题,但我只是想知道如何创建一个与上述 JS 解决方案“等效”的 TS。

Cer*_*nce 4

你需要

(1)Hash正确键入对象,以便TS能够识别其键和值的类型

(2)Cache正确键入对象,以便TS能够识别其键和值的类型

(3) 将累加器键入为boolean, 而不是true,以便内部回调可以返回truefalse<boolean>(这可以通过将类型参数传递给来完成.reduce- 使用泛型比 更可取as

class Solution {
    solve(nums: Array<number>): boolean {
        const Hash: {[key: number]: number} = {};
        const Cache: {[key: number]: string} = {};
        
        for (let val of nums) {
            if (!Hash[val]) {
                Hash[val] = 0;
            }
            Hash[val]++; //implicit else
        }
        
        const val_arr = Object.values(Hash);

        return val_arr.reduce<boolean>((accum, curr) => {
            if (accum && Cache[curr] !== 'unique') {
                Cache[curr] = 'unique';
                return true;
            }
            return false;
        }, true);
    }
}
Run Code Online (Sandbox Code Playgroud)

另一件需要考虑的事情是——JavaScript 不是 Java。如果您有一个只包含单个方法的类,没有对实例变量的引用,那么从结构上来说,定义一个普通函数会更有意义,例如:

function solve(nums: Array<number>) {
  // function implementation
}
Run Code Online (Sandbox Code Playgroud)