On a related note, I've become a gigantic fan of Slonik, https://github.com/gajus/slonik, which simultaneously (a) makes it extremely difficult to expose SQL injection attacks while (b) still letting you write SQL in a very "natural" way using template literals.
It takes advantage of a somewhat-not-well-known feature of Javascript template literals in that you can apply functions to them, e.g. sql`SELECT foo FROM bar WHERE id = ${userEnteredValue}`. No need to manually escape userEnteredValue, the sql template literal function does it for you.
You get the same benefit of "template literals" but the data and query are separated at the DB level. The DB knows what is data and what is query therefore any attempt at escaping from SQL will be quashed there.
That's what the library does. It just uses tagged template literals[1] so that it "feels" like you're writing a template string, while really it's a prepared statement.
It takes advantage of a somewhat-not-well-known feature of Javascript template literals in that you can apply functions to them, e.g. sql`SELECT foo FROM bar WHERE id = ${userEnteredValue}`. No need to manually escape userEnteredValue, the sql template literal function does it for you.