top | item 35079971

JavaScript and TypeScript features of the last 3 years

464 points| Killusions | 3 years ago |medium.com

265 comments

order
[+] jakubmazanec|3 years ago|reply
I love this thread, it has two of my favorite HN topics: 1) People shitting on JavaScript not realizing that their "obviously better" solution was considered and found not a good solution. 2) People shitting on TypeScript not realizing that conditional types and template literal types are awesome. I really like those type-safe routers (https://tanstack.com/router/v1/docs/guide/type-safety) and fully-typed database clients (https://www.edgedb.com/docs/clients/js/index#the-query-build...).
[+] Waterluvian|3 years ago|reply
Typescript is one of those things that makes me so productive that I have absolutely nothing to argue or prove. Their loss.
[+] pharmakom|3 years ago|reply
I really dislike how unpredictable the typescript compiler can be. What I mean is, there isn’t a simple set of rules I can understand to know when annotations will be required. Most of the time, this doesn’t matter, but occasionally it blows up and development comes to a screeching halt. Contrast this to, say, Java and ML type-systems, which are highly predictable.
[+] sph|3 years ago|reply
On the other hand, Stockholm Syndrome is an underrated and under-researched effect in software engineering.

There are people ready to defend with their life the most obtuse, inane piece of technology, just because they have invested a non-negligible amount of time getting used to its quirks, that they become completely blind to its faults, and start to believe those very quirks are actually positive and to be cherished.

[+] mattpallissard|3 years ago|reply
> TanStack Router is built to be extremely type-safe.

This is alludes to my only major complaint about typescript. IMO, something is either type-safe or it ain't. I don't like how the JS bleeds through if you aren't careful.

I'm not a TS hater by any means, I use it regularly and am usually pleased. I just can't help but compare it to the [S,Oca]ML compilers I'm so fond of.

[+] DarkNova6|3 years ago|reply
There is so much wrong with JS, the only reason it is used is because people are literally forced to.

It took a long time for js devs to accept the notion of a compiler with TS. While TS is an improvement, it’s only a localized one. No chance ever, any other language could have replaced it.

[+] moltar|3 years ago|reply
Have you used EdgeDB in prod? I’m itching to try it, but am too worried about general instability. Seems like too many moving parts. Love the DX though, it’s really clean and well thought out.
[+] Ezku|3 years ago|reply
From the comments here, I was expecting to find myself hopelessly out of date, and to end up with a migraine trying to parse through a mindnumbing list of changes. Turned out I was mistaken.

  > Me: oh, cool, they fixed so many tiny things I had bumped up against
  > Some others: oh no, why are things changing
I'm not getting it. Maybe I'm reading this wrong, but to me these seem pretty obvious small issues to smooth over.
[+] itslennysfault|3 years ago|reply
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!!

[+] hn_throwaway_99|3 years ago|reply
> - 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 }`;
[+] stasm|3 years ago|reply
> - # private... not sure why they didn't just use the "private" keyword, but I don't care. I almost always use TypeScript anyways

One of the reasons was to allow private and public fields of the same name, so that subclasses are free to add own public fields without accidentally discovering private fields of superclasses. There were many more considerations that went into the design: https://github.com/tc39/proposal-class-fields/blob/main/PRIV....

There was a heated debate about this and the choice of the # sigil back in 2015 at the time private fields were being designed: https://github.com/tc39/proposal-private-fields/issues/14.

[+] treis|3 years ago|reply
>* EXCEPT IF I WANT TO USE AN ENUM/TYPE AS A KEY IN AN DICT WHICH I REALLY WANT TO DO!!

It's better just to use an actual array for enums:

myEnum = ["E1", "E2"...] as const

type myEnum = typeof myEnum[number]

That gets you both an enum type and an enum array you can use at runtime

[+] anamexis|3 years ago|reply
I've used globalThis for polyfills in code that needs to run both in the browser and on node.
[+] maxpowa|3 years ago|reply
WRT Enum as key in object:

  enum TestEnum {
    Fizz = 0,
    Buzz,
    Bar,
    Baz
  }

  type EnumKeyedObject = Record<TestEnum, string>;

  type EnumKeyedObjectAlt = { [P in TestEnum]: string };
[+] 5Qn8mNbc2FNCiVV|3 years ago|reply
Isn't Record<EnumType, whatever> working?

Then instantiate like:

``` { [EnumType.First]: ..., [EnumType.Second]: ... } ```

[+] Izkata|3 years ago|reply
> - 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

What's funny is the go-to example of using it for translations is just wrong: It only does numeric indexing, so can't be reliably used with languages where words would be in a different order. You still need a library or something that builds on top of it to handle that.

[+] tengbretson|3 years ago|reply
Regarding your last point, I think the general consensus in TypeScript is to avoid using enums entirely.
[+] manv1|3 years ago|reply
"when I see it in a code base I won't be so confused at least"

When I first started using node way back when I discovered all kinds of idioms in use that I had never seen. It was a confusing few weeks for sure.

[+] progx|3 years ago|reply
"??=, &&=, ||=" Yes they are, i stuck always when i see them. I think we just need more practice and need to see them more often until it becomes normal. Currently i avoid to use them.
[+] cagmz|3 years ago|reply
> - 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)

You and your team didn't understand how Promise.allSettled behaved?

[+] illiarian|3 years ago|reply
> 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

A while back I wrote that "Tagged Template Literals Are the Worst Addition to Javascript" https://dmitriid.com/blog/2019/03/tagged-template-literals/ and I still stand by it.

The fact that someone uses them in a somewhat nice fashion in an sql library doesn't change the fact

[+] manv1|3 years ago|reply
"The only programming languages that people don't hate on are the ones nobody uses." - someone online

Negative indexes might actually be useful.

At some point I actually need to read the actual language specs, I guess.

[+] panzi|3 years ago|reply
Object.hasOwn(obj, name): Finally! That took long. Why would you even think that obj.hasOwnProperty(name) would be ok? If its unclear what properties there are you can't expect that the hasOwnProperty property to be working correctly. Always had to do the Object.prototype.hasOwnProperty.call(obj, name) dance.
[+] transitivebs|3 years ago|reply
We need an equivalent "All AI breakthroughs in the last week explained"
[+] Killusions|3 years ago|reply
I took the time to explain all the latest (and some older) JavaScript and TypeScript changes, including code examples.
[+] game_the0ry|3 years ago|reply
As a swe that works with typescript / javascript, I find this post exhausting.

Am I the only one? Am I a shit swe?

Edit - comments seem to suggest I was asking this question seriously. I was not, I was just (sort of) joking.

That being said, front end engineering is rapidly changing all the time, so the confidence I have in knowing I will always have work to do (read that to mean: a job) is satisfying.

[+] __ryan__|3 years ago|reply
It’s exhausting because: _____

If you find yourself struggling to articulate it, seriously and honestly consider whether you’re simply choosing to be stressed about it.

I’m speaking from experience here.

[+] SketchySeaBeast|3 years ago|reply
I don't find it exhausting. There's some stuff I already use, some I'll remember, some I'll forget, and one day I'll probably google for one of these features, but until then it's not going to weigh on me.
[+] IshKebab|3 years ago|reply
I don't think it's that bad but I wish they'd focus more on improving the terrible JS web API rather than adding language features.

I mean they are adding features like static initialisation blocks when we only just got String.replaceAll(), and they somehow managed to fuck that API up despite it being explicitly a replacement for an existing bad API!

Where are all the containers? Sorted sets/maps? Why can't I even map an iterator?

[+] Killusions|3 years ago|reply
I think one can both learn about the new features without feeling the need to use them all or refactor old code.

My biggest learning while writing this was just how much is possible in JavaScript and TypeScript now, but I also realize that a lot of this I will not use myself or only use to understand some really specific code.

[+] rwalle|3 years ago|reply
It's understandable of you haven't touched JS for a few years. But if you work with JS/TS a lot and are not aware of/already using many of the features listed here, you need to ask yourself (or maybe your company) if that's ok. A lot of these are very nice features that are used daily -- they help code to be cleaner and more concise, and you can work more productively.
[+] dspillett|3 years ago|reply
You're certainly not the only shit SWE if you are one. I used to be a good all-rounder, but I've stagnated badly for years everywhere but the database. I should probably have shuffled to management (I understand more than I can do!) but I hate the very idea.
[+] jenadine|3 years ago|reply
> #private: […] This is not recommended for TypeScript projects, instead just use the existing private keyword.

Why not? I was told the opposite: now that the feature is in JS natively, it can be used.

[+] nickpeterson|3 years ago|reply
Not to be the perpetual Luddite, but I hate how much programming languages change. I don’t particularly like go as a language (good board game though), but the minimal changes over time starts to feel really correct.
[+] temporallobe|3 years ago|reply
For me, the most awesome and useful change to Javascript has been the addition of private and static modifiers, although the implementation is kinda weird (why use “static” keyword but not “private” and the # sigil instead?). I use both TS and JS professionally but much prefer native JS and use it in my personal projects, however, the closer native JS can get to TS, the better, as I really do appreciate many of it’s features.
[+] jankovicsandras|3 years ago|reply
" Negative indexing (.at(-1)): When indexing an array or a string, at can be used to index from the end. It’s equivalent to arr[arr.length - 1) " sic arr[arr.length-1)

This is wrong. Array.at can get, but not set the value. So they're not equivalent.

console.log( arr[arr.length-1] ); // works

arr[arr.length-1] = 1; // works

console.log( arr.at(-1) ); // works

arr.at(-1) = 1; // ReferenceError: Invalid left-hand side in assignment

[+] Killusions|3 years ago|reply
Thanks, I edited it to include this, just to make it clear.
[+] dmix|3 years ago|reply
Is it me or are Tagged templates a recipe for hard to read code?

Just the way it extracts the substrings into arguments for unpredictable strings. It doesn't translate to readable code.

I'd much rather use repetitive template strings. Unless I was doing some really fancy string manipulation. Or make my own functions with explicit arguments.

[+] jimmaswell|3 years ago|reply
Not mentioned: importmap is supported in Firefox as of February. Also supported in Chrome and upcoming for Safari. Just in time as I finally started getting more into cutting edge JS with a personal project - job's been stuck on older JS for a long time and I haven't done personal projects in just as long.

I've been running this project straight in the browser with no JS compiler. Are JS compilers going to be on the way out now?

[+] rwalle|3 years ago|reply
Import map is an HTML feature and not in any JavaScript specification. JavaScript language does not care about how to find files.
[+] qwerty456127|3 years ago|reply
Is there a complete list of proper modern JavaScript features and examples covering all and only the features and styles which are modern (not neccesarily this new, perhaps some are 4-year-old) and relevantant + those which have never been replaced by any newer so are sill relevant although old but excluding outdated features and styles?
[+] t8sr|3 years ago|reply
If you asked me what the biggest areas were where JS needs work, it wouldn't be "syntax sugar for separating numeric literals", it would be stuff like "integers".

At this point I'm almost afraid to ask, but if JS can evolve in major ways like this, why can't we address some of the basic shortcomings of the language?

[+] Andrex|3 years ago|reply
> String.prototype.replaceAll

14-year old me hacking up my first JS on Freewebs.com is doing backflips right now.

...And 31-year old me is saying "What the fuck took them so long?"

[+] delaaxe|3 years ago|reply
There must be a mistake in the "Exact Optional Property Types" section?
[+] k__|3 years ago|reply
Are * and default the same?