Trying to override a variable inside a function and get an error: "Block-scoped variable '...' used before its declaration.ts(2448)"

Trying to override a variable inside a function and get an error: "Block-scoped variable '...' used before its declaration.ts(2448)"

我正在编写一个 typescript 函数,它接受一个数字数组(即 type: number[])并计算它的平均值。此外,我想考虑输入数组何时可能包含一些 null 值。为此,我添加了一个参数,当设置为 true 时,告诉函数在计算平均值之前删除 nulls。

但我无法找出正确的方法来执行此操作,因为我无法覆盖函数内的输入。

这是我的 calcMean()

代码
function calcMean(arr: number[], nullRemove: boolean = true): number {
    if (nullRemove) { // if TRUE, which is the default, then throw out nulls and re-assign to `arr`
        const arr: number[] = arr.filter((elem) => elem !== null);
    }
    // then simply calculate the mean of `arr`
    return arr.reduce((acc, v, i, a) => acc + v / a.length, 0); // 
}

然后我得到一个错误:

Block-scoped variable 'arr' used before its declaration.ts(2448)

我也尝试使用 let 来代替 const,但它没有解决问题。

我在这里错过了什么?

两种选择:

1。不要重新声明它,只需重新分配它:

function calcMean(arr: number[], nullRemove: boolean = true): number {
    if (nullRemove) { // if TRUE, which is the default, then throw out nulls and re-assign to `arr`
        arr = arr.filter((elem) => elem !== null);
        // ^^^ No `const` here
    }
    // then simply calculate the mean of `arr`
    return arr.reduce((acc, v, i, a) => acc + v / a.length, 0); // 
}

一些人认为重新分配参数是糟糕的风格(我不是其中之一,前提是函数像你的情况一样非常小,但我理解这个论点),所以或者:

2。分配给不同的变量:

function calcMean(arr: number[], nullRemove: boolean = true): number {
    // Remove `null` if requested
    const a = nullRemove ? arr.filter(elem => elem !== null) : arr;
    // then simply calculate the mean of `arr`
    return a.reduce((acc, v, i, a) => acc + v / a.length, 0); // 
}

您问题中的代码目前不允许 null 值包含在 number[] 参数中。

我希望我的代码能够明确说明正在发生的事情,因此如果 null 可能混合在 number 的数组中,我会明确地将它们转换为 0 在没有被删除的情况下:

TS Playground

/** Each null element is either omitted or converted to 0 */
function handleNullValues (arr: readonly (number | null)[], omit = true): number[] {
  return omit ?
    arr.filter((value): value is number => value !== null)
    : arr.map(value => value === null ? 0 : value);
}

function calcMean (arr: readonly (number | null)[], nullRemove = true): number {
  const numbers = handleNullValues(arr, nullRemove);
  return numbers.reduce((sum, n) => sum + n) / numbers.length;
}


// Test
console.assert(calcMean([null, 1, 3, 7, 9]) === 5); // ok
console.assert(calcMean([null, 10, 1, 3, 7, 9], false) === 5); // ok


编辑:更新以响应

TS Playground

function calcMean (arr: readonly (number | null)[]): number {
  let count = 0;
  return arr.filter((value): value is number => {
    const isNumber = typeof value === 'number';
    if (isNumber) count += 1;
    return isNumber;
  }).reduce((sum, n) => sum + n) / count;
}


// Test
console.assert(calcMean([1, 3, 7, 9]) === 5); // ok
console.assert(calcMean([null, 1, 3, 7, 9]) === 5); // ok