About Me: I've been a professional web developer for just over 10 years now. I'm currently the lead web development instructor at Better Coding Academy, and as part of what I do, I post videos on our YouTube channel at https://www.youtube.com/c/BetterCodingAcademy.
(Subscribe for awesome web development content!)
Six months ago, I made this post on Dev: TypeScript is a waste of time. Change my mind.
To my delight, the comments section became an amicable yet passionate discussion on the temporal economy of the typed language.
It has been six months. I have written over 10000 lines of TypeScript code in a production environment, and I am now writing this article as a follow-up to the thoughts I expressed in my original post.
I've now written over 40000 lines of Flow code and over 10000 lines of TypeScript code for various production environments. I'm by no means a perfect developer, and even though I've been coding for 10 years now (cries in existential crisis) I like to believe I am intellectually flexible enough to change my mind upon receiving new evidence.
Okay, so how exactly has your opinion changed?
I made four main points in my original article:
- The pros aren't really pros.
- Typed JS is long and difficult to read.
- Typed JS is still... untyped.
- What's so bad about untyped JS?
I no longer agree with all four of these points, and I'll share what I've learned regarding each of them below.
The pros aren't really pros.
At the time of writing the article, I felt that a large number of TypeScript evangelists would make an appeal to authority (namely large companies) for compelling reasons as to why you should use TypeScript.
In response to this, in my previous article I wrote:
However, if you honestly think about it, this argument falls apart reductio ad absurdum:
Big companies use TypeScript, therefore I should use TypeScript.
Big companies also use legacy systems, therefore I should use legacy systems.
Although I do not retract this statement, I have come to understand that there are some "pros that are really pros" when it comes to using TypeScript over Vanilla JavaScript. Let me explain.
Typed JS is long and difficult to read.
I used the following example in my original article. This is the untyped version of the code:
import React from 'react';
import ApolloClient from 'apollo-client';
let apolloContext;
export function getApolloContext() {
if (!apolloContext) {
apolloContext = React.createContext({});
}
return apolloContext;
}
export function resetApolloContext() {
apolloContext = React.createContext({});
}
And this is the equivalent version in TypeScript:
import React from 'react';
import ApolloClient from 'apollo-client';
export interface ApolloContextValue {
client?: ApolloClient<object>;
renderPromises?: Record<any, any>;
}
let apolloContext: React.Context<ApolloContextValue>;
export function getApolloContext() {
if (!apolloContext) {
apolloContext = React.createContext<ApolloContextValue>({});
}
return apolloContext;
}
export function resetApolloContext() {
apolloContext = React.createContext<ApolloContextValue>({});
}
With respect to this code, I said:
I genuinely don't find them more readable in most cases.
However, I've changed my mind on this part. After seeing the syntax each day for a couple months on end I've become quite accustomed to it. Additionally, I have learned to appreciate the benefits that this syntax provides over its untyped counterpart.
Typed JS is still... untyped.
because TypeScript compiles down into JavaScript, regardless of how carefully designed your types are, there always is the chance that a different value type sneaks into a JavaScript variable. It's unavoidable - JavaScript is still untyped.
I've changed my mind on this part as well. Admittedly, there is the chance that an unexpected value of any type "sneaks" into somewhere you don't want it to go. However, that doesn't mean that static type checking is completely redundant.
It's like saying: because there's a (very) small possibility I'll injure myself, that means I should never do any form of weight training, or exercise for that matter.
It feels strangely hypocritical correcting myself, but I'll continue on.
What's so bad about untyped JS?
If there is hard statistical data that using untyped JavaScript vs. TypeScript means that productivity decreases by any significant amount (if at all), then I wouldn't mind the verbosity of TypeScript.
...and this is where I am yet to see that data.
Admittedly it's a lot to ask for, and I don't expect such evidence to (ever) become readily available.
However, regardless of whether we have such statistical data or not, I still believe that untyped JavaScript "isn't bad". In fact, I'll probably be sticking to Vanilla JavaScript for the majority of production projects from now on, and here's why.
Wait, so you're not using TypeScript anymore?
Nope. I used it for a couple months, and got into the serious nitty-gritty, from writing custom type declarations, to using union types, to using nested generics and more. It definitely was not a "light" usage.
However, I've decided to stick with Vanilla JavaScript for future production projects.
There are a few issues I uncovered when working with TypeScript that I still consider unbearable given my present circumstances:
TypeScript is not well-documented.
I'd absolutely love to be proven wrong on this one here.
Sure, there's plenty of documentation when it comes to typing your number variable or your simple function, but what about, for example, a higher order function that creates another function which manipulates an object you pass into it in a certain way? I'm sure it's possible to type such a function using generics and whatnot, but I've many times been unable to figure out how via the official TypeScript docs.
Oftentimes I'll run into some sort of TypeScript issue. Perhaps it's caused by my code, perhaps my configuration, or perhaps it's legitimately a bug in TypeScript. Where a similar issue in, say, React, can be easily resolved through online searches within a couple minutes, I find myself constantly spending more than one hour on each of these concerns, and this leads me perfectly into my next point.
I still need to write code, faster.
Since adopting TypeScript, I've noticed a substantial decrease in my rate of feature production. Which makes sense - I'm literally writing more code to get the same feature done.
Oftentimes I have hardly any wiggle room on project deadlines.
Oftentimes my priority is to ensure a feature is well-tested and production-ready as soon as possible - and to me that means using various types of testing to increase my confidence in the code.
Unfortunately, this means that oftentimes my priority is not having self-documenting, statically typed code.
This is a sobering reality I face. If you are not constrained by these deadlines (maybe you work in corporate? :P) then perhaps TypeScript will work just fine for you. However to the rest of you out there, I want you to know that TypeScript will take more time. It absolutely will. But it's up to you to decide whether that extra time is worth it.
Thank you for reading!
To those of you who took the time to read through my article, thank you! I really hope that my content has been insightful.
I post videos on on YouTube at https://www.youtube.com/c/BetterCodingAcademy, featuring tutorials on various tech buzzwords such as React, Node.js, TypeScript, GraphQL, Microservies, Docker, and more. :)
As always, I come from a place of love and humility, and I would greatly appreciate it if you left non-scathing discussion or criticism in the comments. I would love to learn more about this and have my viewpoint shaped as well.
Happy coding!
Top comments (37)
I don't use TS for my personal projects, transpilaton is weird sometimes and I don't want to waste time struggling with complex types. BUT! I use @types libraries all the time with webstorm 😍 it help a lot, a lot and a lot, to autocomplete and check in IDE, so in reality, TS helps me to work much faster.
THANK YOU TS COMMUNITY!
So basically "I don't use X because I don't want to learn the complex parts of it", not saying it's not a valid reason, but dont't try to make it seem like "I don't use X because the complex parts of it are really hard to use"
Nope, i don't use X because i don't want to. I don't need more reasons and you neither, it is a valid reason. I know that sometimes it's hard to respect others decisions about software choice, our community is full of rage and anger, but if you try, you will be happier and you will learn faster.
As I said, thats a perfectly fine reason. In the original comment it sounded like its the type systems fault for beeing complex, maybe I'm so tired I'm interpreting the meaning of the message wrong, maybe it wasn't that. I wasn't trying to like start a fight or anything (sorry if my message was worded like that was the case), I just pointed out I don't agree with the way you categorise complex types as a waste of time
The type checking that TypeScript provides is super awesome. Glad it's working out for you!
Surprising article! I thought your conclusion was going to be that you changed your mind on Typescript (going from 'negative' to 'positive'), and that you concluded that TS is good/useful after all. But towards the end it became clear that you didn't really change your mind - you still think that TS is a waste of time for most projects! Didn't see that coming when I started reading the intro.
I would say that my attitude has definitely shifted. If we're using a positive/negative scale, I went from somewhat negative to definitely on the positive side.
I would say that this is no longer a fair evaluation. I'll say that TS is useful for certain things; however, having used it and properly considered it over many months, I cannot honestly say that it is "good" as a blanket statement. As with all technologies, TS has its imperfections, and I'm far more interested in spreading knowledge about those than I am in blindly promoting any specific technology.
My opinion is still not fixed in stone, and may evolve over the years to come. With better documentation, more bugfixes and better learning resources, I am very hopeful that my impression of TS will continue to improve. :)
But, having said all that, your conclusion is that you won't be using it on the majority of your projects.
I've used it on one project and I found it intriguing. But yes, it takes time and effort to reap the benefits. I think my opinion is similar to yours: TS isn't rubbish, it is well thought out and potentially useful, I just haven't figured out if the benefits are big enough to justify the effort.
I agree! It is well thought out, but I think it has a long way to go, and definitely isn't for everyone, all the time. :)
I'm just curious, what do you mean by "ts has a long way to go", except for your documentation point (which I don't really agree with, the examples of "complex types" you listed arent that complex actually, the only time you can have some problems is when going in the complex dependent type teritory), not trying to say ts doesnt have problems, actually, I bumped into a lot of them myself, but your article doesnt seem to point any major ones
Documentation is key. If a library or code provides good JSDoc or TSDoc, that's more important to me as a user than if it compiled and has good 'type coverage' or even test coverage. $.02
That being said, I find using libraries with good types, and with great TSDocs, to provide a nicer and faster dev experience for me as a user.
I made an experimental library, lit-tea, that ports the elm architecture (simple redux basically) to typescript now that TS has exhaustive switch statements over unions; the library uses lit-html (templates) rather than react components. This is a far cry from my deaire for rich TSDocs, however the types are able to proivde a much more direct understanding of the system than react prop types or vue typings imo.
I agree completely with your point on documentation. Tests are crucial for user-focused insurance, whereas documentation is crucial for developer-focused insurance.
I've also attempted using typescript the past couple of weeks on a side project.
TLDR; it doesnt seem to work too well with parcel(importing svgs)
I do find that the experience of using typescript was worthwhile, but I'm never using it again on a solo project unless I'm also using apollo-graphql.
Basically, I couldnt agree more with your views Lucas :)
Thank you for the post
You're welcome!
You can import svgs very easly with typescript, just make sure to write a declaration file
True, but I think parcel itself has some unresolved issues.
Try this out.
github.com/parcel-bundler/parcel/i...
What TypeScript does for me is Type Hinting. Using JavaScript, in many cases, is like walking in the dark, unless the author is kind enough to write a JSDoc for me.
When I use JavaScript, I write a lot of JSDoc as well. Even though it is not as strong and easy as TypeScript.
Also, it seems to me that TypeScript tries to break compatibility with JSDoc, at least in VSCode. Must be a hidden plot of Microsoft.
VSCode has surprisingly good type hinting for Vanilla JavaScript as well, and I'm optimistic that it is going to improve!
The type hinting in vscode for vanilla js uses the ts language server under the hood
Typescript looks like it was invented so that people could still write code that resembles C#. Why not embrace javascript as it was designed? How will the story of Typescript not end pretty much like coffeescript, for example? After all, coffeescript looked like it was invented so that people could still write code that resembled ruby. Where is coffeescript today?
I'm not sure it'll end up like CoffeeScript, as its syntax is nonetheless quite similar to that of JavaScript. It mostly does a good job of being an "addition" to JavaScript, unlike CoffeeScript which looks like an entirely new language lol
Its popularity means it's also probably not going anywhere soon. Nonetheless, I do agree that it looks a LOT like C#... C# devs probably have a really easy time getting used to TypeScript lol
Coffescript died a lot quicker, typescript is 8 years old at this point and it doesn't seem to be going anywhere
Hey Lucas, I read your original article one day when i was aggravated by typescript. And now while I'm not so on the fence about typescript. My coworker and I think that typescript on the frontend with react is a bad idea. Couple the big slowdown that typescript has, especially when writing connected components or other HOC. (we've actually cheated and decided to to //@ts-ignore and not write the HOC normally required for properly typed injected props for the connect HOC) The other big annoyance we've noticed, particularly when working with redux is that like you said typescript is poorly documented. Finding examples of how to properly write those connected components was a frustrating experience.
Whats your opinion on typescript with react? We don't think its ready or worth it atm.
On the backend with nodejs typescript seems to be a lot more beneficial when writing something more than a REST api. e.g. an application that holds state or brokers messages to websockets or other protocols. Whats your opinion on this backend?
I don't think the frontend/backend makes a difference here - to me it's all about developer productivity. In some instances I feel like the amount of time I'm spending (sometimes double or triple just to get a complex function typed well) is not worth the potential amount of time I might be saving (couple minutes of debugging with well-written tests, maybe).
At the end of the day, if it works well for you - great! Regardless, my message is just one of caution and proper evaluation, and not letting the hype get to you. :)
I seriously agree with this article. I find TypeScript to be a kind of exchange of productivity for correctness, which, to be honest, in the real-world is less practical. Think about it this way — would you rather have end-to-end tests that test your production-ready application or TypeScript complain in development? Think carefully, because the answer is not obvious. TypeScript takes time to get right. A lot of time. This is time you could be testing your application in the wild, rather than testing its correctness in development. Yes, there is some crossover here, but it’s not 100%. When you use TypeScript, you are betting on TypeScript helping you more than hurting you.
What I’m trying to say is that TypeScript is a very steep bet. But something about this is unsettling — Go is not dynamic, and I find writing Go to be easier than TypeScript, so what gives? I actually think the crux of the problem is that TypeScript is trying to fix JavaScript. But what if JavaScript doesn’t need fixing? Then TypeScript actually doesn’t pay for itself. I say all of this as a cautionary tale for developers. I’ve been turned on and off multiple times by TypeScript. Ultimately, I think that some languages introduce so much complexity up front that if you try to wrangle them in later, you’re optimizing for the wrong problem.
I’m sure some of you will say that TypeScript makes you more productive, and if you are one of these people, that’s great. But I found I ran into similar problems as Lucas — TypeScript’s documentation and error messages are far from friendly, and TypeScript as a system starts to break down the more complexity you introduce into your app, e.g. recursive types, etc. I’m having bugs where my IDE and app don’t even agree. And I simply don’t have the time to find the root cause of every problem I run into, because most of these problems are concerned with correctness.
Fun read, thanks for sharing.
I'm by no means a TS lover, but I'd argue that you may be missing one of the biggest benefits, and that is working with other developers. TS provides an in-code contract for you to express how your code works in terms of parameters coming in and values returned by those functions.
I don't care how much JSDoc you have, when the rules are baked into the execution of the code, things are easier to understand, and less likely to result in a bug.
You're right! I brought up my thoughts in that on another comment under this post:
So yes, absolutely, just like how tests are for improving UX, TypeScript is for improving DX. :)
Turning from Java to Javascript in 2016, I felt extremely naked without type notations, as if leaving home without my pants. It looked like some array would rebel and leak into a number at any moment and I would try to divide it by some other NaN and catastrophy was inevitable. But I was wrong, that's why we test our code. And my services from that time are stable in production to this day.
But I never overcame that insecurity and I did have an Angular project to maintain so I was used to Typescript, and after one year I decided to shift every backend code too. And I'm the architect of a team so I'm responsible for everybody's code, and gradually applied some very strict Tslint rules too.
I'm in a corporate yes, but only because what used to be a start-up back then grew up. Unreasonable deadlines are the only deadlines I know.
There are many reasons to take different people through different paths towards the same goal, and my experience was very positive in ways pure JS isn't suppose to deliver.
I still write quick js files to test a theory or even a PoC, but TS became my default.