0

When using certain initial values in Array.reduce, TypeScript reports a strange error in this Playground example.

The error Argument of type 'number' is not assignable to parameter of type 'never' is shown for c in line 2 of the following example:

const foo = [1, 2, 3].reduce((p, c) => {
    p.bar.push(c);
    return p;
}, {bar: []});

document.write(`foo=${JSON.stringify(foo)}`);
1
  • 1
    The empty array accumulator is automatically typed as never. An alternate approach that should work would be to type accumulator p in the first line Commented Jan 17, 2020 at 16:45

1 Answer 1

1

This error occurs when you have strictNullChecks enabled and for a good reason. Your initial value for Array.reduce is {bar: []} which cannot be resolved to a safe type. Is the array any[] or number[]? Hence, TypeScript assumes it is never[] as it cannot infer the type of the array from the usage inside your lambda (it only works the other way round).

By the way, without strictNullChecks the array has type undefined[], but the flag basically replaces all occurenced of undefined as a type with never which causes your example to fail since and assignment of the form const foo = []; is of type never[] with strict settings.

In order to fix this issue you have to set your initial value to {bar: [] as number[]} to explicitly type the array and it works:

const foo = [1, 2, 3].reduce((p, c) => {
    p.bar.push(c);
    return p;
}, {bar: [] as number[]});

document.write(`foo=${JSON.stringify(foo)}`);
Sign up to request clarification or add additional context in comments.

9 Comments

Thank you for the explanation but I'm still very much confused. Given you explanation it is all about the untyped array but why does [1, 2, 3].reduce((p, c) => { p.push(c); return p; }, []); then work without error?
@doberkofler It does not work with strictNullChecks enabled either.
Correct. My mistake. So this case can actually simplified to the following example const foo = {foo: []}; foo.foo.push(1); that generates the same error. But why can i then use const bar = []; bar.push(1); without error?
Yet again bar is of type never[] and it does not compile for me with strictNullChecks enabled.
@doberkofler What the flag does is to replace occurences of the type undefined such as your arrays which are undefined[]. It replaces all occurences of undefined with never to cause compile time errors unless you explicitly type them.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.