TypeScript developers are a lucky bunch: for us, Christmas comes four times a year when the TypeScript team releases a new beta version. This is our opportunity to try out the latest features. TypeScript 5.0 beta came out on January 26, 2023. Let's take a look at what's new!
First, a note on version numbers. With semantic versioning, a change in the major version typically means breaking changes. And the number after 4.9 is 4.10, not 5.0. TypeScript doesn't really do semantic versioning. The whole point of new TypeScript releases is to find (existing) issues in your code. So in that sense, each release contains breaking changes.
Microsoft also counts in decimal. The version after 4.9 is 5.0, not 4.10. This causes some pain every tenth release since many packages on npm declare that they require
email@example.com. This can either hold you back on an old version of TypeScript or lead to fragmentation, as I noticed with TypeScript 4.0 back in 2020:
TIL I have five copies of @typescript in node_modules! @orta was there much debate about whether the version after 3.9 was 3.10 or 4.0? In terms of branding and math, I agree it's 4.0. But since so many packages pin tsc@~3, this seems unnecessarily disruptive… pic.twitter.com/FBiAxZBM15— Dan Vanderkam (@danvdk) October 23, 2020
Why doesn't TypeScript do versioning in the usual way? The definitive answer comes from TypeScript Tech Lead Ryan Cavanaugh:
The trade-off for getting millions of dollars of engineering investment in the TypeScript project is that marketing gets to control version numbers to a certain extent.
So there you go. Every 2.5 years we have to deal with this extra pain. At least marketing didn't decide that the version after 3.1 was 95!
Every new version of TypeScript has the potential to surface new errors in your code. As long-time readers of this blog know, the code samples in Effective TypeScript are all type-checked. One of the benefits of this is that when new TS versions come out, I can type-check my book against them. Sometimes I learn that my book is out of date and sometimes I find new bugs in TypeScript.
TypeScript 5.0 didn't surface any new errors in Effective TypeScript. Huzzah! 🎉
There were a few new errors in my work project. All of them involved comparing
The full code looks like this:
val has type
string | number while
maxVal have type
Not helpful, JS! TypeScript has always barred comparisons between strings and numbers. Now the noose has tightened just a bit more and you may have to be more explicit about conversions.
The TypeScript team claims a 10-20% speedup in build times with TypeScript 5.0 beta. I was able to confirm this both on my work project (Delve) and in running literate-ts against Effective TypeScript:
- literate-ts / Effective TypeScript:
- TS 4.9.5: 194.12s
- TS 5.0-beta: 181.31s (6.6% speedup)
- TS 4.9.5: 46.36s
- TS 5.0-beta: 38.27s (17.5% speedup)
const type parameters are the one new language feature in this release. These are like
as const but applied on the function declaration, rather than at the call site.
The applications I see for this in my own code are mostly small quality of life wins. For example, my work project has a
DropdownList component that takes a list of options and a selected option. The list of options should be a tuple of string literals, and the selected option should be one of those literals:
With TypeScript 5.0 we can move the
const into the declaration of
And drop the
as const at the callsite:
If you inspect
options here, you can see that its type is inferred as
readonly ("Option A" | "Option B" | "Option C") whereas before it would have been inferred as
readonly string. Nice! If you factor the list of options out into a variable, though, the context will be lost and you'll be back to using
What else is this useful for? Back in 2020 I talked about the
tuple helper function:
What if we use a
const type parameter on
tuple? Interestingly, it becomes a sort of "deep tuple":
Is this useful? Maybe. There are always compelling applications of new language features and I'm sure I'm missing some here. Do you have a use for
const type parameters? Let me know in the comments!
With TypeScript 5.0, enums become a little more sane. Whereas this was OK in TypeScript 4.9:
It's an error in TypeScript 5.0:
So are enums OK now? As it turns out, the newfound sanity is only surface deep:
TypeScript enums are complicated and problematic. While they become slightly saner with TypeScript 5.0, I still say "avoid them."
There are more changes in the new release than what I've written about here. Check out the release notes for full details. With any luck, a release candidate (RC) will arrive on February 28th and the final cut of TypeScript 5.0 will be out on March 14th.