Personally, I favor languages that go "almost too far" in the opposite direction, e.g. Elixir. In Elixir, operator[] (a.k.a. the Access protocol) is generic across several types, but the semantics are very strictly constrained; not only does the access have to "mean" getting some kind of element from a container, but it's also only defined where it has a fixed O(1) time-complexity.
This sort of design being conventional in Elixir, means that you can usually predict, just from the lexical environment (a.k.a. "the code on the screen") what the runtime behavior will be of said code—which includes being able to "read off" a time/space complexity for the code—without needing to check how each ADT involved has implemented its generics, let alone having to check for implicit type coercions.
x = 5;
(no var declaration). Extremely easy to do by accident. Lots of these will be left for backwards compatibility. In JS errors often go silent and I developed a strong dislike for any language that does that, including Vimscript and Lua (and I do like Vim).
We all know that is global.
Nowadays you use `const` or `let`.
Any JS developer will have a linter that will tell them incase they somehow made that mistake.
I'm not saying that it breaks the language, but it definitely is irritating, especially if you're not using a linter.
Also, I like knowing which variables won't be reassigned (const), and which will (let).
Mostly because JS is not the only language that I'll be working with at a time, and if I'm dancing between three or four and they have similar syntax, then mistakes creep in.