Use the erasableSyntaxOnly TypeScript compilation flag

TypeScript v5.8 ships with the new erasableSyntaxOnly compiler flag.

It disallows using the TS features which emit additional JavaScript output, due to being outside of official ECMAScript specification.

In this lesson we'll see what TypeScript features get affected and why exactly.

Check out the playground link with the code.

Share with a coworker

Transcript

[00:00] Most of the TypeScript features are erasable. That means that important type definitions or type information is being removed from the JavaScript output. For instance, let's create a let obj variable which is going to be an object with a name string property and let's assign it into an example object which is going to define the John Doe name. We can see that the important type information which is being used by the compiler is being removed from the output. Why?

[00:33] Because we want the JavaScript output to be executable in various JavaScript run times, which don't need to be aware of TypeScript specific features. So this Erasability relates to majority of the TypeScript features. However, there are some important exceptions. And one of them is a well-known enum type. So the main idea behind a union is to create a narrowed, a specific range of values that can be used to provide a certain runtime value.

[01:08] So here we can see that we're using the medical specialty with a dot to access one of the values, let's say we'll choose a neurologist. What we can see on the right hand side, the JavaScript output is that there is some runtime overhead that is being created in TypeScript. So the enum is being transformed into becoming a dictionary where all these values become a key and their equivalent values in this case are a number. We can make it a string, we will do that in a while. Though we can see that there is some JavaScript overhead.

[01:50] Now there is an equivalent and we can create the same medical specialty here with an underscore just not to make TypeScript throw an error because the name has been already used And here we've got the general practitioner, surgeon, and others just sticking to the convention with the uppercase letters for the constants. So this is a TypeScript string literal union. These are simple string values just gathered together to create a union type. If we want to create an equivalent specialty variable using this medical specialty, then what we've got here is simply just a string. There is no JavaScript overhead whatsoever, just pure variable declaration.

[02:37] So this can be totally wiped out. So right now our enum is number-based and this is because each value is just being assigned into 0, 1, 2 or whatever we can assign over here just if there was a reason to do that. Though we could make it a string-based enum so this is available by just providing the string equivalent So most often that's what we do. We just copy paste what is the value over here. What is important that if we finish the thing so that our enum compiles, still it doesn't change the fact that this enum construct, this enum feature of TypeScript does introduce some runtime overhead and some additional runtime JavaScript code.

[03:27] The only thing that changed is that Instead of the internal implementation, internal memory representation being a number, it's a string value. But still in our code base, in what we write and in what we read, we're going to deal with the enum.thevalue here anyway. So whatever type of enum it is still it does introduce the additional JavaScript runtime code. So all these features that do introduce the additional JavaScript code are considered troublesome for many different reasons and what we could do until this point is basically to avoid for instance enum in favor of the native string literal union in TypeScript for instance. However from version 5.8 there is a new compilation flag that allows us to basically disable all the features that will introduce unnecessary JavaScript runtime code.

[04:28] So when we walk into the tsconfig or when you open the tsconfig.json file we need to search for the erasable syntax only. So what it does is it disallows the runtime constructs that are not part of ECMAScript. So after we turn this on then all features that are additional pieces of TypeScript syntax that are not part of the ECMAScript, which essentially boils down to the fact that some additional JavaScript runtime code had to be added, then they are simply disallowed. And this will throw the compilation error saying that this syntax is not allowed when erasable syntax only is enabled. Now, many of you could think that, hey, I've been using enums or other features that I'm going to mention and I've been happy with them, like why would I turn this flag on?

[05:22] So the whole point of introducing this erasable syntax only is that there is a long ongoing process of allowing TypeScript code to be executed within native JavaScript runtimes. This will take more time, but this is just a single step in achieving this. And we're all going to obviously benefit from being able to run TypeScript in JavaScript runtimes. So enums is just one example of disabling pieces that are not part of the ECMAScript specs and also introduce the additional code. But there are some more of them.

[06:01] And one of them is, well, not the class itself because class is a part of the ECMAScript specs but actually creating the properties from within the constructor's parameters. So if we carry on with this approach and that is we just specify What are the parameters of the constructor and specify what are their corresponding types? Now this is absolutely correct because this would be a valid ECMAScript specification part. Now we just add the type so that they can be raised. However, if we add the accessors and that is private, protected or public, now we can see that here there is some additional code being added into the constructor.

[06:51] So there is the assignment. So this comes from C sharp, but essentially this is a shorthand syntax to not only create the parameter, not only create the property, but also do the assignment within the constructor. So this is also not going to be allowed for the same reason this syntax is not allowed when erasable syntax only is enabled. Finally, the last piece of the syntax that is going to be disabled using the erasable syntax only are the namespaces and again the same error message. That is because whenever we're using namespaces, again, an additional JavaScript runtime code is being introduced over here.

[07:40] But this is not a big problem since TypeScript namespaces have been mostly abandoned by the TypeScript community in favor of native ES modules.