DEV Community

Cover image for TypeScript is a waste of time. Change my mind.
Better Coding Academy
Better Coding Academy

Posted on • Updated on

TypeScript is a waste of time. Change my mind.

I think that TypeScript is a waste of time.

However, with the level of support TypeScript has, I know I'm bound to ruffle a few typed feathers here, but all I ask is that you hear me out.

I'm going to present what I believe to be a rational defense of my position, and then if you want, you can rebut my position in the comments below, and we can have a productive discussion. ๐Ÿ™‚

Wait... read this part first!!!

Personally, I have used TypeScript on a variety of local and production setups over the last year or so. Prior to that and concurrently also, I worked on a full-stack JavaScript app, including over 60000 lines of Flow-typed Node.js code and over 40000 lines of Flow-typed React code.

However, as with all things, context is incredibly important.

Do I believe that there are situations out there where TypeScript should be used?

Absolutely! If your team is already using TypeScript, if you want to write code for other developers who may be using TypeScript - it really depends upon the context. However, I am making the argument that the use of TypeScript within your company project / your personal project / any sort of closed-source, non-library project will probably take more time than if you were to not use TypeScript, taking into account development time, bug-fixing time, time spent discerning and typing libraries, and so on.

I have a couple main points regarding this matter:

  1. The pros aren't really pros.
  2. Typed JS is long and difficult to read.
  3. Typed JS is still... untyped.
  4. What's so bad about untyped JS?

1 - The pros aren't really pros.

The commonly listed pros of TypeScript (and pretty much any popular tech product nowadays) always includes the statement: big companies are using it.

Now, if you're learning TypeScript in order to land a specific role at a company, then Godspeed - I'm not here to debate whether it can get you employable.

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.

But wait, you say, the fact that TypeScript is used by big companies means that it is well-researched and supported! But then agan, the same argument can be made for Flow (static typing library by Facebook), React, Angular, Vue, Ember, jQuery, Bootstrap... wait a second, pretty much every popular library out there!

Other pros that people list include:

  • Having access to future features now - don't need TypeScript for this, you can just use Babel.
  • Working with older browsers - polyfills or Babel.
  • Static typing and type inference - see point below.

2 - Typed JS is long and difficult to read.

Kyle Simpson, proficient JavaScripter and author of You Don't Know JS, doesn't like using arrow functions.

Why? Because, and I quote:

I genuinely don't find them more readable in most cases.

Here's an article he wrote explaining it in more detail: https://davidwalsh.name/i-dont-hate-arrow-functions.

Now, not to try and make an appeal to authority fallacy, but I think that this:

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>({});
}
Enter fullscreen mode Exit fullscreen mode

Code sourced from https://github.com/apollographql/react-apollo/blob/master/packages/common/src/context/ApolloContext.ts

Is far less readable than this:

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({});
}
Enter fullscreen mode Exit fullscreen mode

Do check out Kyle's article on why he doesn't like arrow functions... many of the points he makes there rings true regarding my critique of TypeScript also.

3 - Typed JS is still... untyped.

In truly statically typed languages such as C and C++, different variable types are stored differently in memory. This means that it is very difficult, borderline impossible to accidentally store data of the wrong type in a variable.

However, 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.

The truth is, even if you proficiently use and apply TypeScript (or Flow, for that matter) in every way possible, it's incredibly difficult to completely type all your variables, objects, interfaces, etc. properly. I was working with TypeScript on a Node.js project with over 60000 lines of code, and I found that my interfaces file for my Sequelize database models was over 5000 lines long on its own! I found the file to be mostly redundant, telling me what I already knew, however the reason I wrote it is because VSCode kept reminding me with the red squiggly line that I should type my models.

4 - What's so bad about untyped JS?

No, but seriously - what is so bad about it?

Untyped JS Bad Meme

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.

However, there is no such evidence, and quite frankly, I personally am convinced that untyped JavaScript is more productive. Here's why I think this to be true.

  1. TypeScript is, by definition, longer than untyped JavaScript. As such, the development time is longer (assuming everything else is equal).
  2. None of the benefits purported by TypeScript (better error handling, type inference) are silver bullet solutions. You still need to test, and you still need to properly name your functions and variables. Adding an interface or a type doesn't solve any of these problems.
  3. Although TypeScript does catch some bugs in development, they're usually fairly trivial (using a number where a function expects a string) and can generally be caught by an experienced programmer anyways. With regard to more complicated issues (e.g. race conditions, memory leaks, etc.), TypeScript is completely useless.
  4. Therefore, as you still need to write the same tests and spend the same (or very similar) amount of time debugging and testing your code, whilst writing more code (see premise 1), therefore using untyped JavaScript makes you more productive than TypeScript.

5 - More importantly, look at design patterns and learn to spot code smells.

Here's an extra tip - instead of worrying about whether to use TypeScript, Flow, or untyped JavaScript, learn to write better code through design patterns and avoiding code smells (structural issues in your code). Learn to spot these issues, and also learn to refactor your code so it is better written. This kind of stuff is cross-language, and is what really can take your programming skills to the next level, and turn you from a junior developer to a senior one. ๐Ÿ™‚

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.

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!

Latest comments (246)

Collapse
 
tetthys profile image
tetthys • Edited

That's why I don't use typescript for frontend projects ๐Ÿ‘๐Ÿ‘๐Ÿ‘ And I will drop typescript soon for backend. People use typescript because others use it without something reasonable.

Collapse
 
shailennaidoo profile image
Shailen Naidoo

I agree with a majority of your article, I feel that TypeScript's existence is largely just marketing. If you want a truly statically typed language then go for that but trying to treat TS as if it were a truly statically typed language then you are going to bump your head. It is only type checking at compile time and not runtime.

Collapse
 
desone profile image
Desone • Edited

Typescript is JavaScript annotated for better machine readability at the expense of human readability and productivity.
It is recommended by big techs writing code linting and code assessment tools.
Actual product companies must be careful when they listen to advise coming from cloud providers and tech vendors.
Yes , they have good technical expertise, but their formula/equations of loss/profit is different and their profit might be causing you more expense.

Collapse
 
lid6j86 profile image
Dave Torrey

Here's my personal modern opinion on the matter: I've used Typescript in the past, and I thought it was -ok-, but I think that modern ECMAScript has come a really long way to improve the weakest parts of native Javascript.

The gap between what Javascript natively allows and what Typescript offers has been increasingly narrowing - to the point that modern Js even offers things like private properties (I'll admit, the protected accessor is nice and missing from Js), decorators are in Stage 3, a much better integrated module system, improved scoping, an option between modern class syntax or the traditional function prototyping, symbols, destructuring, await/async, spread operators, etc...

When Typescript first started out, pretty much none of this existed. The one great thing about Typescript is that it's heavily influenced the direction that ECMAScript has gone. However, I'm of the growing opinion that the currently existing shortfalls have shrunk to a degree that I find it often much better to just be able to open up a file and start coding without worrying about any sort of transpiling. Even babel has slowly become less necessary unless you want the absolute latest features.

The typescript support in editors like VS Code and JetBrains tools often works just as well with Javascript if you're willing to put in just a little extra time to use JSDocs. Additionally, things like tuples are on their way to native support in Javascript

There was a time that I thought Typescript was probably essential. It has some pretty useful features, no doubt. but these days I find myself more and more wondering how much is necessary given how much Javascript has improved

Collapse
 
cstroliadavis profile image
Chris

I feel like this article mostly reflects my own opinions on TypeScript.

In my experience, the main "pro" of TypeScript is to impose order intended to deal with the pain of undisciplined developers. JavaScript definitely gives you a lot of rope to hang yourself (and the rest of your team) with.

I've moved over to using TypeScript over the past few years and there are definitely some things that I like about it. For instance, IDEs being able to really know which interfaces you are using and give you better feedback about your code. Definitely very useful.

However, ...

My own experience has been that, as a disciplined developer, for every 5 minutes I gain with TypeScript, it cost me closer to 10 to get it.

With regards to being on a team of undisciplined developers. OMG. If you thought things were bad without TypeScript, just wait until you get undisciplined developers who are just trying to get stuff done with TypeScript. The result is type hell, and trying to do things "right" in that environment is way worse than in a similar JS environment, and that's really saying something.

I haven't used Flow, much, so I can't say if that's better, but I think if you're going to do TypeScript, you're going to need to do it in a way that is not so constrictive. It would be much better to have a really good and strongly enforced Peer Review process in place than it would to replace JS with TS, IMHO. It could simply be that the TS environments I've been in were configured to be overly strict.

I've found that I can fairly easily gain most of the benefits of TS with JSDoc comments, that most IDEs readily recognize. Obviously there isn't much enforcement of types, but again, it feels like the little gain I've seen there is offset by the cost.

Also, debuggers seem to work much better with straight JS than trying to interpret TS in mapped code. When debugging TS, I often find my debugger either ignoring breakpoints, or breaking in very odd places (essentially offset from my actual typescript code), and giving me information that is hard to understand or useless.

The one thing I can say for certain. I can definitely code much faster in straight JS than in TypeScript, and the way I code, it's much easier to fix in straight JS than in TS.

Collapse
 
wrongrook profile image
Tim

Once a language becomes popular enough and starts to be used at "enterprise" level people start trying to turn it into Java/C#. I've seen this happen over and over again.

Collapse
 
captainn profile image
Kevin Newman

A "code length" measure of a language is pretty shallow. It also misses the point of what a static type system gets you, and what the trade offs actually are.

I will concede one point before I move on - some folks go WAY TOO FAR with static type definition, when they should be relying on more core model types, combined with as much inference as you can get away with. If you are writing types using every conceivable feature of Typescript, then you are just doing it wrong, and you are going to hate your types, and that seems to be where a lot of folks - especially library writers, who more often than not, completely over complicate their types. Maybe there's room for a book titled, "Typescript: The Good Parts" to clarify this point.

That said, what is a programming language? There are 3 components to a language:

  • Syntax - the actual written word. Something like coffeescript rearranges the syntax.
  • Static Environment - the aspect of the code that can be understood by reading the written code.
  • Dynamic Environment - the aspect of the code that is only determined at runtime - in JS that includes "types". They are there, but they are resolved in the dynamic environment, that makes javascript a dynamic language.

So what does Typescript add? In addition to a bit of syntax (type spec), it mostly adds a static type system, to the static environment, making it easier to reason about your code, and FAR easier to build helpful tools. JS has quite a bit in its static environment - you can tell the difference between a boolean, a number, an object definition, a class, function, etc. So it's not like it doesn't have types, but the only types that can be referenced in the static environment are those that can be inferred, and that doesn't include the shape of basically any object. The most notable place that breaks down is when you define function arguments. In that case, you end up with a blob - an "anything" type, for every argument, in every function, in the JS static environment.

Without Typescript, to understand what that argument is, and what it's receiving, you need to wait for the runtime - the dynamic environment - to run to that point, and resolve those types. If you like debuggers, or console.log, that's great, now you just have to run you program for each an every scenario that might call that function, and I guess hope no one calls that function from an unexpected location, with incorrect "anything" types (which is easy, because the tools we use can not have a clue what the correct types are for those arguments). You could read and test the function to make sure it behaves correctly with "correct" argument types, but that will not protect you against someone sending in "incorrect" argument types. In order to do that, you'll need to validate the arguments for the correct types - at runtime, which is more code, not less. Always check your inputs! (It's true that Typescript doesn't add type checking at runtime - we'll get to that.)

Typescript addressed that (and other scenarios beyond just the function) by adding the ability to specify a type for each argument. Now, you know exactly what type, what object shape, etc. about the type in your argument. This is a class of unit tests you no longer have to write. Even better, the build time type checker knows, and can tell you not just whether the internals of the function are correct, but also whether any caller of that function has sent in the correct variables, solving an entire class of common errors (no more can't access prop X of undefined), when used correctly.

That thing about a lack of runtime type checks - it's true, but because we can now resolve the types in the static environment, and prove type safety, we mostly don't need to worry about runtime type checks. But if we do need dynamic type checks (say if we want to expose your function to the world in an API, and need to validate inputs at runtime), we can use something like runtypes to translate our typescript types to runtime type checks - making that part where we need to validate your inputs at runtime a cinch.

Honestly, it provides so much benefit, and productivity gains, it's hard to take arguments against it seriously, except those that decry the over-complicated use by some but not all implementers. Yes, that needs to stop, but ditching types is absolutely bonkers to me.

Collapse
 
olafrv profile image
Olaf Reitmaier • Edited

typescriptlang.org/docs/handbook/t...
Duck typing is partially checking types allowing you to fool the concept of "type".

Also this article is funny too: dev.to/jfbrennan/the-reasons-i-don...

Collapse
 
judekeyser profile image
Judekeyser • Edited

Please consider this example, that shows typescript (and likely Flow) type system are not rich enough to be safe. They both miss the crucial points that JavaScript functions have arguments, return type, and invocation context, to be fully known (which would require dependent types, something that TypeScript does not have).

In particular, the following snippet is valid TypeScript, yet yields an undefined at runtime (no cast involved ; "compiles" also in strict mode):

type MyFunction = () => string;

class X {
    private me: string = "I know him, it's me";

    f() { return this.me; }
}

const x = new X();
const { f }: { f : MyFunction } = x;

console.log(x.f()); // Correct display
console.log(f()); // Incorrect display
Enter fullscreen mode Exit fullscreen mode

The language also badly supports prototype inheritance and re-patch.

TypeScript is not a super set of JavaScript, it does not follow idioms and constructions. What can be said I think, is that TypeScript syntactic rules are a super set of JavaScript ones (need confirmation). But as shown above, and what can be shown by playing a bit with prototypes, is that TypeScript type system is not strong enough to support JavaScript idioms and turn it 100% safe.

Collapse
 
maarlon1 profile image
Maarlon1 • Edited

I completely agree, a TS is a complete waste of time. It promotes bad programmers because it tries to catch their variable type 'errors' while every even average programmer knows how to check if a received data is of a right type.

Second mistake, TS tried to lure in OOP programmers making them to think that JS is a OOP strict-type language. It's not! It's a functional programming language with its own strengths and has an excellent object system on its own. Trying to make JS something it is not intended for - a big mistake. If we need an OOP, we should use an OOP language like C# or a C++

Third mistake, TS is clumsy, complicated and it's easy to write bad code that is hard to debug.

Fourth mistake, TS tries to correct only one error, wrong types while it doesn't cover tens of other user mistakes, like forgetting to insert closing parenthesis for example. Should we invent a new language for every possible erroror each?

Fifth mistake, TS compiles to a JS file which completely ignores all TS features and a resulting file is much larger than an ordinary js file, so it's inefficient. JS compilers, especially Google V8 engine has an excellent garbage collector that more efficiently allocates and frees dynamic variable type memory than 99% of programmers would be able thru efficient using of the right variable type.

There is more but let's end it here. Use TS if your employer strictly requires it (although they usually don't know why) and gives you a very good salary for it. Otherwise you may forget it completely

Collapse
 
gibbitz profile image
Paul Fox

Looking at example files from Angular ATM and seeing that they're using the TS extension and nearly none of the type checking and realizing that 90% of the TS code I've dealt with is this way. I agree that typed languages are great for documentation and predictability in codebases, but I find that these are not what TS is touted for.

Usually folks are preaching about how TS helps with Uncaught TypeError in the browser which is almost 100% caused by bad inputs at runtime (not compile time where the TS enforced type-checking happens) or with "finding (or fixing) bugs". From the simple fact that typing is optional in TS and that the buildsystem is enforcing it means there are many ways to hack around the safety that will be exploited by contractors because they are measured on speed and perception of efficiency, not quality or actual efficiency. Which leads to the perception of longer development times which is both true and false with TS.

At the feature level TS does increase development time. Adding a new feature that requires types and interfaces will take longer in TS than ES20XX it's more code, period. That said, TS will make refactoring or spinning up new developers on the project faster and will likely lead to more thoughtful architecture. If you come to development with the mind to rock out small features, then you get way more bang for your buck writing unit tests, but if you are looking to write a new site or platform you get a lot of future benefit from the blueprints provided by a strongly-typed TS codebase. The problems arise when feature teams start writing loosely typed code, neglecting to type or write interfaces. This is like the broken windows of uncle Bob mentioned elsewhere and it doesn't take long before there's a perception that the types are safe, but they really aren't. This is only compounded when non-technical types (or the inexperienced) get the idea that TS means your code is actually less prone to errors just by switching the "j" to a "t" in the file extension.

In the end this is why I prefer writing ES20XX, because I have no misgivings about whether it is type-safe -- it isn't. Then I can spend more time on unit testing and best practices and assume that there will be occasional issues with objects passed as arrays, numbers as strings etc. and look for the errors at runtime or in the unit testing.

Of course the fallout is in the design and onboarding phases and these now require more effort, but to be fair, it's a one-time cost. It's been my experience that business complains less about onboarding taking a few weeks than initial development taking a month or longer, so unfortunately there's no economic pressure to start a project right (using good type documentation).

I think a conversation like this one is aiming to say one is better than the other. If I'd have to side with one, it would be good ol' dynamic typed JS. Not because TS is a bad idea, but it runs into bad implementation every time I see it. I think what we need as a community is a better approach to dynamic types and better support of them in the tool chain. The thinking that dynamic types === bad and static types == good is not really the right thinking here. It's more like tooling for dynamic types === bad and tooling for static types == good. So instead of putting heaps of effort into writing better tools for dynamic typing we're making compiling a dynamic language from a newly invented static one. Why?

Collapse
 
ddemydenko profile image
ddemydenko

all right said
ts is a good thing overall, but you need to keep an eye out to avoid over-engineering and misapplication

Collapse
 
huppopotamus profile image
huppopotamus • Edited

Agreed on all counts, though I think you could add another to your list. I've often heard that typescript is meant to aid developers who are familiar with object oriented languages learn to write front end code in terms they're already familiar with. Personally, I don't think typescript keeps you from having to learn JS or ES6 and how it functions and behaves.

Also, as you mentioned, for me, typescript hinders me more than it helps, and I've not yet found a situation where typescript provided me with anything at all that I couldn't already do myself in ES6 with some simple functions.

If it's up to me, typescript is a hard pass.

Collapse
 
firfi profile image
Igor Loskutov

With all respect to the author, I'm considering only the points/statements of the article.

I strongly disagree, partly because of how the pros/cons are presented.

First of all, the article title invites to a holywar, not to discussion. It's a strongly negative statement, probably in order to catch attention. Well, attention it got.

Secondly, the first point of the article already a strawman. At the first statement, it should be the biggest and the most impactful point, but instead I see fallacy. Who cares about "Big companies" (what specific companies author is talking about?) using this and that โ€” we have our tools to do our job, in a maintainable, cheapest and fastest way possible. (I can elaborate on each point why Typescript achieves all of that, but it's not the format of a comment). "Big companies" use Java 1.6 and SOAP for god sake.

The second point says it doesn't appeal to authority fallacy and yet does the exact thing, additionally twisting it inside out. Indeed, the "authority" statement is about their personal preference about arrow functions but the author moves it onto types with ease. How's that even remotely related?

As to the core of the second point's statement, "typed js is hard to read", it's not clear if the author means any type system altogether as well (in which case it's another holywar topic where the counterpart would say "well untyped code is hard to debug") or is it only about Typescript type system only (then it completely lacks comparison with other languages and has to be dismissed as incomplete).

The third argument โ€” since at the moment of this comment it's 2021 โ€” there's a good example of the same logical circuit covid deniers use: "If masks/vaccines don't work 100% it means they don't work at all".

You stricten your code where it makes sense for business and leave JS where it doesn't. It's a great tool for accomodating to budget and requirements of your business, and to me it's strange to dismiss it as "it's all comes to untyped js anyways". Well, Rust code would all come down to untyped bytecode anyways, does it make its borrow system useless? Java generics would be erased at runtime but does it mean they don't catch bugs at compile time?

The 4th argument is a meme then a request for impossible at the moment โ€” hard performance measurement for development teams. Except for the dreaded LoC measurement, which the author seem to regard in 4.1 as a benefit of untyped JS.

The 5th argument is a grain of truth and I can't disagree with that I know no one who would disagree. But it isn't related to benefits/shortcomings of typed js vs untyped js. You should structure your code well in both cases for sure.

I hope I got the points well enough and someone would find this useful for dismissing the concerns stated in this article.

Collapse
 
nobsob profile image
NobSob

Overloading to the CPU 98% is very bad for your computer.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.