My love-hate relationship with Typescript
Muhammad Usman
Senior Software Engineer @ IKEA Digital ?? Javascript | React | Typescript | Microfrontends
My love-hate relationship with Typescript
Well, you all can understand my pain as how confusing Typescript can be initially but recently I started loving typescript and in this article, I will be discussing my pain with Typescript and how I started falling in love with it when I correctly understood the relationship between javascript and typescript.
TypeScript is a superset of JavaScript
Yes, we have been listening to these statements from all javascript pandits around the globe but it never helped anyone learn typescript. If you look at typescript in terms of syntax then yes this statement looks fine but typescript is a lot more than the syntactic sugar over javascript. all your valid javascript code is still a valid typescript code although the typescript type checker will flag some type errors but typescript will still parse your code and emit JavaScript.
Running tsc index.ts on this file will flag some ts errors but it will still generate an index.js file which shows that typescript code generation is independent of typescript type check which actually feels very weird because what is the point of type checking if typescript is still emitting the same javascript code ??.
After ranting a few months about this I understood that typescript merely does this due to the fact that largely old javascript projects when migrated to typescript require both js and ts files to run so therefore typescript decided to keep transpiler and type check abilities independent and in fact, the production code does not have any types and interfaces, every type that typescript added to javascript is removed so even if things are type checked during development, in production, you won't need them so keeping code generation dependent on type checks does not make sense
Structural Typing
If it swims like a duck, quacks like a duck …
Well, F**k duck let's understand what structural typing is.
Types in typescript are not “Sealed”. Typescript type systems have an open end on types. This means that if the required structure is present in your objects then Type-Check will pass. Type-checker only looks for required structure and residing types inside the structure
Let's consider the following example:
Let's say you are working with some vectors and you have a vector that is defined by the x and y points so you will define our Vector type as
We have defined a type Vector
interface Vector {
x: number;
y: number;
}
to calculate Vector length
function calculateLength(v: Vector) {
return Math.sqrt(v.x * v.x + v.y * v.y);
}
now we will observe that type check will overlook this type error if we add a z attribute to the object passed to calculateLength function
const x = { x: 10, y: 20, z: 30 };
calculateLength(x);
although the z attribute is a dead property for calculateLength but typescript type checker didn't complain because the type-checker only looks at the structure that v:Vector required in order to calculate the length of the vector.
The fun fact is type checker will complain if you directly call calculateLength like this. ??
领英推荐
calculateLength({ x: 10, y: 20, z: 30 });
I have not yet found the reason why the typescript type-checker gives error in this situation, if you know this please add your comment below ??
Code Generation
At the start of the article, I explained how type-checking and code generation work independently of each other. Lets look at code generation more in-depth
We can not check types in typescript at runtime, lets's say you have the following piece of code
Type-checker will throw an error and your program fails at runtime as the Transpiler will strip all interfaces and types from javascript code. There is no Cat and Animal at runtime.
To overcome this issue we can either use classes or have tagged types on objects
I sometimes think why don't we have these types inside javascript where browsers can read them but that would be a breaking change in the javascript world because all plain old javascript projects running would get obsoleted
Because types are striped at runtime therefore we can not have method overloads. Let's consider the following example
Because at runtime types are striped, both add functions would be duplicated. Typescript though provides a facility to do this.
In other cases, we can also use a powerful Typescript feature that is Generics which makes me fall in love with Typescript ??
any type
We have all been there when we are stuck and are tempted to use any type and get away with the type checking but any cause more problems than it solves. It breaks Contracts and can cause billion-dollar errors on runtime.
Because any hides your type design due to this; there are no language services available on any. People love how typescript documents your object types and with a dropdown let the writer know what is available on the object and what is not but with the use of any we have no Intellisense available
Avoiding all the above-mentioned things and properly understanding this relationship of typescript with javascript has helped me truly utilise the power of typescript and has helped me write very effective code in the past few months .
That's all for this week, see you guys with another typescript article next week ??