> It's really far from being ergonomic, unless you're basically just using JS objects as structs. Otherwise you're dancing around its pitfalls and limitations—visibly, in code, not just in your head—to express things that are very simple and clear in pretty much every other commonly-used OO-supporting language.
That might be because I've started OO with JS and mostly did some with it, but in my experience it's fine. I do tend to not use OO as in "object mutating themselves" much though, outside of cases where it's a great fit like a database connection.
> Incidentally, I've yet to see a TS codebase that ties itself in knots to avoid defining a function outside a class, to avoid treating functions as first-class when it makes sense to, or even to avoid a little imperative code outside of objects, here and there.
I haven't seen big codebases like that, but I've had a few collegues coming from Java/C# start every piece of code by writing a class, usually in a "kingdom of names" styles. I'm worried that TS may enable these people even more in the future.
> I have seen a lot of code using HOFs to the point of absurdity, while passing big objects around to a bunch of functions and pretending that's "more pure" than putting those related functions on a class for that object. Or trying to shoehorn runtime-checked immutability into the language, at a performance cost for end users. Or writing their own weird, crippled form of objects in a language that already has them so they can keep things "pure" and let people keep avoiding the Class keyword for... whatever reasons they want to do that (React Hooks).
I'm not defending "functional" (as in ML/Haskell) JS and agree with you here. If people want to do functional programming, there's OCaml, Elm, F#, Scala.js and ReScript, no need to shoehorn that into JS. I think that's an antipattern, just like doing OO everywhere for the sake of it.