`NonEmptyArray`

As the name suggests, an Array that guarantees the invariant of length > 0 and has no empty slots (never sparse). This ensures length always matches the actual count of elements, reduces "foot-guns", and it "matches" the name of the class itself! (the latter point is just an aesthetic reason)

There was a previous post explaining why a new kind of Array isn't a great idea, but (for this case) I believe it makes sense for it to be distinct, as the behavior of multiple methods must be changed (the following lists are non-exhaustive):

  • pop & shift must throw instead of returning undefined
  • reduce doesn't take an initial param, and is guaranteed to only throw what the callback throws
  • splice

Other methods would return new NonEmptyArray instances (or a ref to the same N.E.A.) rather than Arrays:

  • concat
  • fill
  • map
  • toReversed & reverse
  • toSorted & sort

Others are yet-to-be defined (throw? always Array? conditionally return Array and N.E.A.?):

  • slice
  • filter
  • toSpliced

Prior art

Another motivation

What problem is this attempting to solve?

Most of what you're suggesting seems to fall under the bucket of "let's fix the bad decisions related to our current array class", but then you also have, what looks to me like an unrelated idea of "let's make it so the array can't be empty". So echoing what ljharb asked - what is the core problem you'd like to see solved? Is this mostly about having an array type that can't be empty, and the other items are just being thrown in as "we could also fix these at the same time"? Could you expound on why it would be valuable to have an array type that can't be emptied?

These would also need to throw when there is only one item left, or they don't mutate. Both behaviors could be surprising.

Longer term I think that static analysis via TypeScript would be better placed to catch the hazards of working with potentially empty arrays.