在 TypeScript 中推送到嵌套数组

Pushing onto nested arrays in TypeScript

我对 TypeScript 中的嵌套数组行为感到困惑。我想对未知深度数组使用单一类型。

这是我的问题的模型:

type PossiblyNested = Array<number> | Array<Array<number>>; // Limited to 2D, for simplicity. My actual input will be up to 6-dimensional.

const FLAT_INPUTS: PossiblyNested = [0, 1];
const NESTED_INPUTS: PossiblyNested = [[0], [1]];

const PROCESSED_INPUTS: PossiblyNested = [];

for (let i = 0; i < FLAT_INPUTS.length; ++i) {
    const RAW = FLAT_INPUTS.shift();

    PROCESSED_INPUTS.push(RAW); //  Argument of type 'number' is not assignable to parameter of type 'number & number[]'.
                                //  Type 'number' is not assignable to type 'number[]'.ts(2345) 
}

for (let i = 0; i < NESTED_INPUTS.length; ++i) {
    const RAW = NESTED_INPUTS.shift();

    PROCESSED_INPUTS.push(RAW); //  Argument of type 'number[]' is not assignable to parameter of type 'number & number[]'.
                                //  Type 'number[]' is not assignable to type 'number'.ts(2345)
}

我尝试过使用通用模板化类型和递归类型,但都无济于事。我可能不太了解这些。

我已经能够用 'any' 和 'unknown' 满足 TS 和 Lint,但这会导致其他问题。我想不惜一切代价避免这些。

我已使用预期格式的项目成功初始化 PROCESSED_INPUTS(请参阅下一个示例),但我必须在循环之前手动清空它。感觉很笨重

const PROCESSED_INPUTS_FLAT: PossiblyNested = [0]; // include content

PROCESSED_INPUTS_FLAT.pop(); // manually empty

for (let i = 0; i < FLAT_INPUTS.length; ++i) {
    const RAW = FLAT_INPUTS.shift();

    PROCESSED_INPUTS_FLAT.push(RAW); // TS and Lint are now happy
}

有没有更简洁的方法来初始化 PROCESSED_INPUTS 以便动态接收推送的条目,无论它们是数字还是数字[]?我希望这就是我用我的 PossiblyNested 类型设置的......显然不是。

在此先感谢您的帮助!

您的 PossiblyNested 类型表示只有数字的数组,或者只有数字的二维数组。当 TypeScript 计算 PROCESSED_INPUTS.push 时,它使用交集类型作为逆变参数,因此如果数组是 Array<number>,则该方法的类型变为 (...items: (number & number[])[]),它接受 number push 或一个 Array<Array<number>>,它接受 Array<number>.

要解决此问题,您可以将 PROCESSED_INPUTS 的类型设为 Array<number | Array<number>>,它是一个数字数组或一个数字数组。

const PROCESSED_INPUTS: Array<number | Array<number>> = [];

// ...

for (let i = 0; i < FLAT_INPUTS.length; ++i) {
    const RAW = FLAT_INPUTS.shift();

    PROCESSED_INPUTS.push(RAW!); // need non-null assertion because RAW could be undefined
}

Playground link