Anyway, the one place where Typescript isn't great in the fullstack approach is the Database stuff. We used Prismo for the better part of a year, until we eventually moved on to Mikro-orm which has been great so far.
I'm personally not a big fan of OOP or "over architecture", because I've seen how bad it can go too many times. Instead I favour functional programming and keeping things as simple as possible, even having "almost duplicate" code once in a while. So with this in mind, it may strike you as odd that we moved from Prisma to Mirko-orm, but Prisma just clashes with the way we want an ORM to work in so many ways.
Maybe this is by design. Prisma doesn't want to be a "real" ORM after all, but things like having to put everything in a single schema file is bothersome. Yes, you can put it in different files and then cat them together, but that leads to other issues. Like the VSC Prisma extension highlights not working outside the main Prisma.Schema file. More than that though. We like to have "ID, UpdatedAt, UpdatedBy, CreatedAt" sort of things on basically all our models, and since Prisma doesn't have the inheritance I almost never use, that means you need to duplicate it soooo many times. It's also hard to write generic methods for basic CRUD stuff because of the way Prisma uses the Prisma Client Classes it auto-generates to operate. On top of that, migrations can't go backwards in Prisma.
Some of these issues are on the Prisma road map, others aren't, and you're always going to bang heads with an ORM, but Prisma just didn't feel as mature as it's extremely excellent documentation (and marketing) might lead you to believe in my experience.
I can certainly see myself using it again, once their roadmap is a little further ahead though.
Sure, duplication isn't a goal, but DRY shouldn't hold back work as long as it has no meaningful consequence on performance. In some cases, duplication is a good thing, but your average programmer will address duplication by making a routing more complicated and further away from where it's being used. This is often a mistake.
Worse yet is when programmers DRY up tests. Tests are the worst place to be applying DRY. The point of testing isn't to write an entirely new application on top of your actual application. If you're DRYing up your tests a lot, you're probably writing a second application and should probably stop doing that.
We do this the other way around, by using Scala.js so we can use Scala on the frontend as well as the backend. It's very nice.
I've wondered about this approach for a while, but have yet to actually try it in any meaningful context. Do you use a framework like React via Scala.js, or are you doing something different?
It's not as good as EF by a long shot (nothing really is), but for most queries it works fine. You can also use SQL or stored procs for the exception cases which no ORM ever fully replaces anyways.