hmm... I've been using JS/TS for almost as long as they've existed. A lot of these are nice. Some less so. Some quick thoughts:

- Tagged template strings. This just feels dirty to me. Probably won't use, but when I see it in a code base I won't be so confused at least

- matchAll. I've never needed this. I've used match with g a bunch, but I never need the capture group.

- Promise.allSettled. THIS is useful. I've implemented this (under a different name) in almost every code base I've worked on, and got bit HARD by not understanding this behavior long ago (huge production outage that took hours and many engineers to discover)

- globalThis. EW. Don't think I have to elaborate

- replaceAll. It's always annoyed me needing to use RegEx for simple replace all. so Yay!

- ??=, &&=, ||= These seem really useful, but also potentially hard to read, but I think if I get used to their existence they'd become second nature

- # private... not sure why they didn't just use the "private" keyword, but I don't care. I almost always use TypeScript anyways

- static ... YAY! finally. Again, if they could do this i don't see why not "private"

For the TypeScript stuff I'll just say the type system has kinda jumped the shark, but I don't hate it. It's SO robust and of all the new stuff being added I'll maybe use 1/10 of it, but it's good to know I can describe literally anything* with it if needed.

* EXCEPT IF I WANT TO USE AN ENUM/TYPE AS A KEY IN AN DICT WHICH I REALLY WANT TO DO!!

> - Tagged template strings. This just feels dirty to me. Probably won't use, but when I see it in a code base I won't be so confused at least

Tagged template strings are an absolutely brilliant feature and have tons of valuable uses. In particular, many sql libraries in node let you do this:

    const query = sql`select foo from bar where zed = ${param}`;
From a developer standpoint it "feels" just like you're doing string concatenation, but in reality the query variable will contain a prepared statement so that it safely prevents any kind of SQL injection, e.g. it gets parsed to

    {
        sql: "select foo from bar where zed = ?",
        parameters: [param]
    }
There are lots of use cases where things are easily expressed as an interpolated string, but the thing you want back is NOT just a plain string, and tagged template literals are great for that. It's also a nice way to call a parser, e.g. many GraphQL libraries let you do:

    const parsedGraphQLSchema = gql`type Query { foo: Int }`;

I fear that syntactic sugar creates as many problems as it solves. For instance, one might wish to sort the results by whitelisted column:

    query = sql`select foo from bar where zed = ${p} order by ${col} asc`;
Unless the lib implements a real SQL parser for the right dialect, it will quote each expression in the same way, and will either fail or produce a broken SQL.
Definitely a lot of misconceptions around how this would work. Just check out something like slonik, https://github.com/gajus/slonik, which is an excellent implementation.

The example you gave actually isn't valid, because what you're doing is generating SQL dynamically, and that doesn't work the way prepared statements work. That is, you can't have a prepared statement like "select foo from bar where zed = ? order by ? asc", because with prepared statements the question marks can only substitute for VALUES, not schema names. So if you wanted to do something like that it slonik, it would fail. With slonik you CAN do dynamic SQL, that is guaranteed to be safe and checked at compile time with TypeScript, because you can nest SQL tagged templates. That is you can do this:

    const colToSortBy = useFoo ? sql`foo` : sql`bar`;
    const query = sql`select col from mytable order by ${colToSortBy}`;
In that case slonik will know how to safely "merge" the parent and child parsed SQL.