I think Fable strikes the right balance. There are some leaky aspects of how it compiles to JS, but this means that you can quite well use it with existing JS libraries and for things like parsing JSON (you can just cast JSON object to F# records and it'll work).
So, you need to think about something about the JS part when you want to do JavaScript-y things, but you still get plenty of nice help from the F# compiler when writing the logic that the functional-first style makes so much easier.
In my experience with Fable, this pragmatic approach is what makes it great.
Isn't a "JSON object" just a string?
Their isn't actually much of an abstraction in one direction, valid ES6 is valid TS and the types are inter-operable.
Throw in better typing, proper classes, down compiling of async/await to ES3/ES5 (still magic to me) and the ability to progressively port from one to the other (and you can even get a lot of the TS benefits just by annotating your existing JS as a good first step to moving to TS) and for me it was a no-brainer.
I don't think TS is a pretty language but it's a fantastic approach to getting from shitty-A to less shitty-B.
Pragmatism wins for me as much as I'd love to just write everything client side in something else.
Coming from a C# and Python fan, TS hits the mark pretty solidly on all levels.
This is an exact example of what GP was talking about with leaky abstractions though. You don't have to just learn TS to use TS, you need to learn TS and JS.
IMO a proper, strict typed language; and plain Javascript; are both much better options than TS.
I don't understand this. TypeScript is not a different language. It's just JavaScript with some type annotations. If you had never used JavaScript before and learned TypeScript you could immediately write plain JavaScript as well.
If you want to make your own opinion, we have a really good guide here: https://medium.com/@zaid.naom/f-interop-with-javascript-in-f...