The solution we use right now is ts-sql-query [1] which supports automatic type-safety for complex joins, CTEs, subselects etc. I evaluated Kysely as well but found the sql feature set coverage of ts-sql-query better at the time.
I maintain a code-generator [2] for this project that can generate the table mappers from database schema similar to how zapatos.
We don't have as good support for lateral joins and deriving json from database though, which zapatos does really well.
Solutions like ts-sql-query are better when you need to dynamically generate complex sql. With ts-sql-query it is very easy to create sql select statements where multiple individual where clauses, or even joins are conditional based on the incoming filters.
You can choose to use stored procedures etc. for the more complex cases while keeping pgtyped for 80% of the less dynamic use cases. We decided not to go that route to keep most of the application in typescript which we are more comfortable with.
Kysely also provides "automatic type-safety for complex joins, CTEs, subselects etc.".
Gotta love how toxic some open-source maintainers are, bashing other libraries while self-promoting.
I know some of our users use both, zapatos for codegen and kysely for querying.