TypeScript 4.0: What I’m Most Excited About

Fernando Doglio
Bits and Pieces
Published in
8 min readSep 2, 2020

--

On August 20th, the team behind TypeScript officially released its 4.0 version. This is the most advanced version of the language, interpreter, and even their website to this date.

And with the announcement came the list of updates, which surprisingly for a major version change, they weren’t that many. Don’t get me wrong, they’re major changes that required a lot of design work and a lot of coding hours by a lot of people. And in this article I’m going to cover the major ones, if you want to read the official release with everything that changed, you can click here.

So without further ado, let’s get to the list of the changes I’m most excited about, shall we?

Class Property Inference from Constructors

Number one of the list is this little puppy. Every time the language (or the interpreter) works in your favor in order to save you time and keystrokes, I’m up for it. In this case, TypeScript is now performing control flow analysis to understand what kind of values you’re assigning to your class’ properties. If the analysis is able to determine that there are no unreachable paths, then it’ll be able to assume their types.

Let me explain with a quick example:

The second version of the class has one code path (the IF statement) that is not always going to be used, which means that first_name and last_name won’t always have a value assigned with this code. And because of that TS’s interpreter won’t be able to infer the type for them. The first example though, with clear code paths, is a perfect sample of how you can avoid having to define the types and let the interpreter infer them from your logic.

Tip: Share your reusable components between projects using Bit (Github). Bit makes it simple to share, document, and organize independent components from any project.

Use it to maximize code reuse, collaborate on independent components, and build apps that scale.

Bit supports Node, TypeScript, React, Vue, Angular, and more.

Example: exploring reusable React components shared on Bit.dev

Labeled Tuple Elements

This is a relatively smaller update compared to the previous one but you can now label elements inside your tuples.

Essentially, what this change was addressing was the fact that if you define a function with a rest parameter, when reading that function’s signature or even when reading the IDE’s tooltip for that function, the actual intent for it is not entirely clear. Look at the following image:

The tooltip states params_0 and params_1 , in this case, for such a simple function this wouldn't matter, but you can see how, for a more complex function, not having names for these parameters can harm readability. So with TypeScript 4.0, you can now add the labels and you’d have an improved tooltip like this:

But wait a second, this is not the only use for these labels. Thanks to them, you can now create type-level overloads like this without any issues:

The tooltip will show all three overloads, and thanks to the labels, they will make a lot more sense than something that says param_0: string, param_1: number .

A few considerations about labeled tuples:

  1. If you use labels for one item in the tuple, you have to use them for all elements.
  2. You can also define optional elements in the tuple, by taking advantage of the label by adding a ? at the end of it:
type Person = [name: string, address?: string]

Variadic Tuple Types

This one has a very interesting name, doesn’t it? It took me a while to understand it, but let’s go step by step.

We’ve already covered the concept of tuples, but just to be sure, a tuple is essentially a list with a pre-set length and where the type of every element is known. So the following are valid tuples:

type PersonParams = [name: string, age: number]let me:PersonParams = ['Fernando Doglio', 36]

Tuples, as we’ve seen above, now can have named elements as well, but the point about them, is that they have this pre-set structure, which we can use to define the rest parameter of a function (again, already somewhat covered above, but let me elaborate):

Notice how the rest parameter always needs to be the last one. We’re limited by that, because of how JavaScript has defined this property. However, variadic tuples allow for a more flexible definition by letting us put the rest parameter wherever we want.

In fact, with variadic tuples, we can also define generic types, which essentially let us create semi-defined tuples, where we can leave room for flexibility, let me explain:

So, as you can see, with variadic tuples, we can define a basic structure for our types and then extend them in order to add whatever extra we need into it.

That’s cool and all, but what can we actually do with this? Well if you apply this flexibility to function property definition, you can define patterns. For example, having a callback as the last parameter, is a very common pattern in Node.js with asynchronous functions. You can define something like that with variadic tuples in TypeScript:

As you can see, I actually defined two tuples here at the top of the code, one for callback functions, since there is also a very well known pattern where the first argument is the error and the second (and potentially others) contain the data of the “happy path” (where there are no errors). The second tuple makes use of the pattern and creates a new one where the callback function is the last element in an undetermined list of parameters.

Finally we’re using these tuple definitions to define our own functions, and you can see how easy it is to use these generic templates of functions to define our own custom ones, that follow the same pattern.

So, in the end, variadic tuples are here to simpify the way we can define a generic tuple, which we can then use anywhere (including on function definitions) to create specific versions of it following the same pattern.

Some Editor Improvements

Other than the above changes (and other minor ones I’m not mentioning here), version 4.0 brought some editor-specific changes to the table, such as:

Convert to Optional Chaining

In case you don’t know what optional chaining is, is a new feature from JavaScript, which allows you to write chain your property access code (or your chained method calls) in a way that if one of them doesn’t exists (or returns null or undefined, thus cutting the chain short) the code won’t throw a nasty exception (you can read more about it here).

Before this feature, you would have to make sure every step prior to the final link on the chain existed before actually accessing it, something like:

obj.a && obj.a.b && obj.a.b.c && obj.a.b.c.d()

Now, you can select that code and click on “Convert to Optional Chain expression” and the editor will refactor that code for you.

Note that this was tested on Visual Studio Code using TypeScript 4, I don’t know how other editors might handle this change.

/** @deprecated */ Support

This allows you to add that comment on top of the methods or functions you’re trying to deprecate and the editor will issue a related warning when suggesting auto-completition options:

Notice the name of the function, that means you should not be using it anymore.

Again, this test was done using VS Code, other editors might change the way they handle this notification.

Breaking changes

Finally, before closing this article I’d like to quickly go over the breaking changes from this version, because they’re the ones that might affect you the most.

DOM type definition changes

Their lib.d.ts definition changes removing the document.origin object. This was done because it only worked with older versions of IE and Safari. You should instead use self.origin for the same result.

Overriding property accessors with properties

This uses to be an error only if you used the useDefineForClassField option, but now overriding your property accessors with a property ( and the opposite as well) is always going to be an error:

Deleting only optional properties

Now, anything you want to delete with the delete operator has to be optional (actually, either optional, or of types any, unknown or never ). Which makes sense if you think about it, because if you’re planning on deleting something, that something needs to specify somehow that it might be undefined at one point of the execution of your code, otherwise you might start seeing unpredictable behavior, which is exactly the opposite of what we’re trying to achieve by using TypeScript in the first place.

Conclusion

There are a few minor things I’ve left out, mainly because they don’t add A LOT to the table, but then again, if you want to see the full list of changes, check out their official statement.

What do you think about the new features from TypeScript 4? Are you excited to start using it? I know I am! Which one is your favorite? Mine is definitely the variadic tuples, I love being able to define generic patterns that can then be applied and specialized everywhere!

Leave a comment down below with your favorite ones and let’s discuss!

Learn More

--

--

I write about technology, freelancing and more. Check out my FREE newsletter if you’re into Software Development: https://fernandodoglio.substack.com/