I'm really sorry if it's duplication but I couldn't find existing issue.
Code
new Array(3).fill()
Expected behavior:
The JS output for this is just:
[undefined, undefined, undefined]
I know there are more ways to fill dynamic empty array probably better ways but this use case serves many people in order to accomplish something like:
new Array(15).fill().map((v, i) => ({_id: `${i}`}))
Actual behavior:
Throwing the following error: "Expected 1-3 arguments, but got 0"
I will be glad to create a PR to migrate the definition of value property to optional.
This is not defined as optional according to the spec
https://tc39.github.io/ecma262/#sec-array.prototype.fill
22.1.3.6Array.prototype.fill ( value [ , start [ , end ] ] )
It'd also be extremely bad for TS to allow calling fill with no arguments on arrays without undefined in their element type.
I don't really see why you'd want to call fill just to put undefined into the sparse slots in the first place? The only observable difference between new Array(3).fill() is hasOwnProperty, which would be a weird thing to use with an array anyway.
I see your point, actually, the specification said that only start and end are optional but the behavior itself is like I describe, if you pass no variables it just means that value is undefined.
I don't really see why you'd want to call fill just to put undefined into the sparse slots in the first place?
Because I can't iterate over empty array using map/foreach/reduce/etc, see the following example:
new Array(15).map((v, i) => ({_id: `${i}`})) // output: [empty x 15]
new Array(15).fill().map((v, i) => ({_id: `${i}`})) // output: [{_id: '0'}, ...]
Now, again it's maybe not the most right way to create a daynamic array and iterate over it with map but as far as I know it's pretty common.
Nvm, I guess we can close this issue.
For anyone else stumbling across this that happens to have the same problem I was having:
I was trying to create a range function (equivalent to Python, but I didn't need the step argument)
private range(start: number, end: number) {
return Array(end - start).fill().map((_, i: number) => i + start)
}
and was getting this error. In this, case, it was easily remedied by using 0 as a placeholder instead of the implicit undefined:
private range(start: number, end: number) {
return Array(end - start).fill(0).map((_, i: number) => i + start)
}
I still believe value should be made optional to allow looping in a declarative style:
Array(4).fill().forEach(doSomething);
As one would do in Javascript. True, you can overcome this by passing undefined or 0 to fill but it adds useless noise to the code.
Most helpful comment
For anyone else stumbling across this that happens to have the same problem I was having:
I was trying to create a
rangefunction (equivalent to Python, but I didn't need thestepargument)and was getting this error. In this, case, it was easily remedied by using
0as a placeholder instead of the implicitundefined: