Understanding TypeScript Philosophy
“Not engaging in ignorance is wisdom.”
— Bodhidharma
Prologue
I heard of TypeScript for long, most are about its type system. However, I never got the chance to write a TypeScript project, despite a simple Obsidian plugin. Now, when I firstly craft a TypeScript project, I think how difficult it can be? Just JavaScript with types, huh?🤔With this thought in mind, I built some total 💩. I can’t even dare to look at it!😨
After some deliberate consideration, I rewrote the project, and started to understand the philosophy behind TypeScript. And in this post, I’m going to share with you some of my thoughts. Since I have much experience in JavaScript and other languages, I’ll focus only on high-level concepts.
Philosophy of TypeScript
First of all, I recommend you to read TypeScript Design Goals.
Overall, you can take TypeScript as a wrapper around JavaScript. It enables strict type checking to avoid unnecessary errors. And since it is only a wrapper, it will eventually become pure JavaScript after compilation.
Type
Since TypeScript is famous for its “type”, let’s talk about type first. In my point of view, the term “type” in typescript is different from that in other languages. It is some kind of “contract” between you and the compiler. A good example can be how TypeScript handles object.
For example, we have an object { "name": "Tony" }
. In JavaScript, we can only guess what is inside an object.
1 | function foo(obj) { |
But in TypeScript, we can specify what type of object we want.
1 | interface Person { |
The keyword interface
might be a little confusing at first, as it has totally different meaning in other languages. In TypeScript, it is a compile-time type, telling the compiler what is inside this object. So in this example, we know there is a field name
in obj
.
Even though interface
in TypeScript can work similar to other languages like Java, the fundamental difference is that it will be erased when translated to JavaScript. So it cannot be used for runtime type identification.
interface
or class
If you are familiar with Java, you may have the impulse of defining plenty of interfaces. However, in TypeScript, you must resist this eagerness. Like we just talked about, interface
in TypeScript is merely a compile-time type, unlike Java, in which interface
is an object. So, when you want an interface
equivalent in TypeScript, you can consider abstract class
.
However, like many other object-oriented languages, TypeScript doesn’t allow multiple inheritance. In this case, you have to use interface
.
Pitfall
Now that we have the type system, you may think that determine the type of an object is a piece of cake. However, there is some tricky scenarios. Look at the code below, we have two functional interface.
1 | interface NumberConsumer { |
You may take this for granted, but don’t. After compilation, all types (number
, string
, etc, and interface
) are wiped out. That is to say, in the example above, instanceof
will cause compile error! And since all types will be erased, these two consumer interfaces are of no difference!😱
The solution is to convert them into class
, so that we can use instanceof
. Take NumberConsumer
for example.
1 | class NumberConsumer { |
instanceof
can only be applied to class
.
References
There are already many wonderful articles on every aspects of TypeScript, just go for them.🫡
- The Philosophy of TypeScript
- How to Check the Type of a Variable in TypeScript
- When and how to use interfaces and classes in TypeScript
Epilogue
In a word, TypeScript features compile-time type checking and saves you from the question of “what is it”. So, happy coding. ᓚᘏᗢ