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:
- 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?
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>({});
}
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({});
}
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?
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.
- TypeScript is, by definition, longer than untyped JavaScript. As such, the development time is longer (assuming everything else is equal).
- 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.
- 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.
- 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!
Top comments (254)
UPD: I turned this thread into article dev.to/stereobooster/type-system-f...
Ok let's start constructive conversation by fixing some terminology: JS is typed language, it is dynamically-type-checked language (or some people short it down to dynamically typed). JS has types: string, number, bool etc. JS has type errors (not much, but still)
JS has implicit coercion, which may create impression that there are no types in JS. Read more here.
So the question of use or don't use TS boils down to: do you want to do static type checking or not? (Dynamic type checking always there). And there is a trade of: you need to write a bit more code (type annotations) in order to make static type checker work. It's up to you to decide if it worth it or not.
As well, you may be confused by soundness of type system. Some type systems are sound e.g. they can prove there are no type errors. TS is not sound (
any
type), but you can bulletproof it with tsconfig, by setting all strict checks to true. And by prohibiting usage of explicitany
.You can make a bridge between static type system and dynamic type system. Check that type are valid dynamically on the input (which is unknown and uncontrolled) and rely on the static type checker through the rest of the programm
for example:
read more about io validation here
Thank you for your input! Allow me to respond and clarify:
Yes, I know. However, I wanted to differentiate between TypeScript / Flow-based JavaScript and JavaScript code that doesn't have TypeScript / Flow. I was first going with "plain", but then again, technically you can have JSX and other non-JS features without static types, so that's why I settled with "untyped".
Yes, I agree completely. However, I also believe that it is not worth it in the majority of cases, and that many people are misguidedly using TypeScript believing that it will save them time when in fact it only slows down development in both the short and long-term.
This is true; however, in my experience this only leads to lots of red squiggly lines. It's impossible to do completely strict types in TypeScript / JavaScript, and there's always going to be that one case that cannot be fixed with this. Before you know it, you've got half-types and hacked code all over the place, and that's something that's not satisfying at all, especially when you've spent an extra 20-40% of development time writing up types, downloading type libraries and exporting interfaces.
You sure can, but I would argue that if you want true type safety and security you should look at a statically compiled, more lower-level language. For example, in many large companies the API that interacts with the database is almost always written in a statically typed language such as C++, C#, Java, etc. - I don't think that TypeScript is the solution here. Plus, importing a function
makeSureItIsAString
seems like overkill just to make TypeScript support complete.Once again, thank you for your detailed response, and I hope my response has been appropriate!
Iβm really disappointed to hear this same subjective phrase again:
I was hoping to find some objectivity. At a minimum, can you please try to convince me that TypeScript slows you down more than it speeds you up?
Consider the fact that I wanted to rename a variable yesterday and VSCode let me do it (and it can only do it accurately because of TypeScript). It changed the variable in 78 files. And this is important: it didnβt just do - βfind and replace...β it did it intelligently. To refactor a variable name in JS would have taken a very long time and I would have had to regression test the entire codebase to make sure I didnβt break anything. I would estimate that a full regression test of my application would take 1.5 days.
And you also forgot about the fact that TypeScript helps to communicate your meaning to future developers. Isnβt that important?
βCommunicating your needsβ / TypeScriptβs value from a Buddhist perspective (part 1)
Cubicle Buddha γ» May 29 '19
So if it helps significantly with refactoring and helps you be a better coworker, then why is it a waste of time?
Good point, ease of refactoring is a place where static typing helps.
My experience was the same: I was forced to do numerous refactorings over big codebases, all done by pressing two buttons thanks to TypeScript, refactorings which would otherwise have taken hours with plain JS. TypeScript is a godsend for the JS ecosystem in my opinion.
Vscode refactors plain js just fine. Typescript does not help with that.
I don't think that's true across multiple files and variables. Especially when multiple classes/interfaces have the same variable names
Ah - you're renaming a variable in an interface? In that case, yes, probably vscode can do that thanks to typescript, and wouldn't be able to do it without it.
OTOH, all the times I did this, I did a global search&replace, eyeballing to make sure, and having the tests for extra verification.
Uh, wait why are you using a single variable across 78 files? If I have to understand 78 files to understand a feature it sounds like you have bigger problems.
Thatβs a lot of judgement Jordan. You seem to be making some assumptions.
For a moment, suspend your assumptions and consider the fact that we had a valid reason for updating the the name of a property on some data. The reason the variable change effected 78 files is because we renamed a property on a data object that we use throughout the entire system. And since we have many api tests, end-to-end tests, unit tests, and more it caused a large change. But thatβs the beauty of TypeScript... I can make a change that effects the entire system without causing any quality concerns.
So while your assumptions involve a change to one feature, in reality this change effected all features. When you take a functional / data-oriented approach itβs not uncommon to have many transformation functions that manipulate the data. And since I currently work on a data visualization UI, there are a great many ways that the users want the data to be transformed.
Does that clarify how one variable name can ripple out? Hopefully it communicates how TypeScript allows my team to continuously refactor with safety and without having to spend a bunch of time updating tests just because we learned that we originally misspelled a property on the data an API returns.
Yeah, you're right I did judge. Sorry. I don't know your codebase, I just find it odd that a single variable would exist across 78 files. Feels wrong to me. Something like KISS or maybe SRP come to mind. But again I don't know your codebase.
I think what they were doing is renaming a key in an interface, like going from data.online to data.isOnline
Or adding
data.timestamp
. With TS you automatically get notified of all the places where this data has to be set and also you now automatically know everywhere you usedata
that it also has atimestamp
property. Also, TS ecosystem goes further than that, you could have Protobuf definitions that might be updated becausedata
is serialized and sent over the network to multiple other services, and with the updated TS typings everyone just knows about this change and can update their code accordingly. And yes, thisdata
interface could be used by hundreds of files across multiple services and git repos.Actually, I might be mistaken, but VSCode uses tsserver to better understand your code and do stuff like refactoring, IntelliSense and stuff.
TypeScript isn't only able to perform static type checking on explicit types, it also infers types quite well. It's even possible to write plain JS, enable
allowJs
andcheckJs
on yourtsconfig.json
and let it infer and type-check stuff for you.This also takes me to another point: in my experience I hardly type stuff other than function parameters; typescript can, usually, infer the rest. So arguments like "you write more code" get a bit weaker, IMHO
This is what I don't get. If you're just gonna mostly do normal js stuff anyway, then whats the point? Shouldn't you just comment your function and describe the expecteds anyway?
This isn't rhetorical nerd snark. I'm really want to know.
One thing to note is that most of the stuff is inferred. So by typing function parameters, almost all data in your app will have an inferred data type (because knowing the parameter types will automatically result in knowing the return types).
you had the same variable in 78 files!? and you're lecturing us about bad design?
This article has some misinformed opinions being reported as fact. I donβt mean that as an insult, I am just sad that there is no empiricism involved. Allow me to clarify:
All of those languages are weakly-typed when it comes to the MOST important aspect:
Do you see how big of a problem it is that C# allows reference types to be implicitly nullable? That means that you can never know if your data is there are not. :( But with TypeScript you can have confidence in your code. The only languages that have strict null are TypeScript, Kotlin, and Swift. Can you see now how your subjective statement above is both incorrect and misleading? I feel like itβs the equivalent of βthe cool kids are using C#.β
Thereβs no reason to write functions like
makeSureItIsAString
when libraries like io-ts do all of that work for you of ensuring type accuracy at compile time AND runtime. So if youβre looking to build an enterprise-grade app, io-ts or tsoa are wondeful tools to eliminate bad data from even getting through the front doors.Let's use softer tone. Everybody has holes in their knowledge, it is ok as far as person willing to learn and take part in reasonable conversation. (Conversation was pretty reasonable so far. β€οΈ@parkroolucas. The title is a bit harsh, but I guess this is meant to be clickbait).
Weakly-typed/strongly-typed is ambiguous terms. See here
Yes. How many of these anti-TS articles are there? But when you look at the usage rates, most of the developers who try TS are interested in using it again.
I totally get you β€οΈ. What I'm saying if we all switch to this tone, it would be hard to have constructive conversation
Β―\_(γ)_/Β―
(Yes author used the provocative title and text, yet somebody should stay cold-blooded)I don't know much about TS (and not a fan of JS, but let's leave that out of this), but I do know a lot about both C++ (static typing) and Python (dynamic typing).
If your code is filled with red squiggly lines from any linter or other static analyzer, you can almost certainly depend on your code being the problem, not the analyzer!
The same flawed logic in what I just quoted at the top is the reason C++ developers are afraid to turn on
-Werror
: "but, but, my code won't compile, it'll just give lots of errors.I've seen that issue in nearly every language I've worked in, so it simply tells me that if someone is working in TS, and is avoiding strict mode because "too many red squiggly lines," you can bet the house they've been writing bad code. Chances are, in fact, they're using TS as if it were nothing more than JS-with-type-hints-on-top...and utterly eschewing the patterns and logic one must follow when working with types.
All that to say, if someone's gripe is too many red squiggly lines, I wouldn't trust the quality of their code in that language.
JSX is typed as well - it's just
React.createElement()
and you can attach dynamic type checking with PropTypes. Or in typescriptOr you can use them both like described here.
Let's stick to correct usage. Untyped means there are no types or what is the same, there is only one type. For example, assembly is untyped language it has only one type - bit strings, Lambda calculus is untyped language it has only lambdas.
In general it should be possible. The other question if you want or not. Don't mix up two argument.
You realise that all those languages are not type safe?
Java unsound, C unsound
C# unsound
It means it is totally possible to write program in all of those language which will crash at runtime because of type error.
Don't confuse static types with type system soundness.
You don't need them everywhere you need them only to validate io e.g. user input, server response etc. There are libraries like, io-ts which helps to simplify this process.
I wouldn't say "in general", I would say "in theory" - however, in practice it is commonly the case that you don't write 100% of the code you use; and as such, you cannot confirm the validity and "typeability" of the code you are given.
That was not my point, and I overstepped when I said "true type safety". Obviously TypeScript does not provide sound type safety and neither do the languages I've listed; however, they do have much stronger, native checks for static typing that are built into the languages, as opposed to TypeScript which still transpiles down before then being interpreted - quite a few layers there where errors can occur.
Could you give an example of when you would need to validate and when you wouldn't? Seems weird to have to validate whether user input is a string, for example.
If you expect string and you read from the html input you will get string. But if you, for example, read state from URL and decode it and expect some arguments to be numbers, things can go wrong here. Or if you, for example, use
JSON.decode
to get response from the server, you need to make sure that response is in correct format.I would validate all user input, I meant to say, that reading IO is typically not that big compared to other logic of application.
Why do you think so? Typescript is quite advanced type system it is based on latest research (and written by the same people who wrote C#, Anders Hejlsberg for example). So this claim needs a bit more evidence.
The fact that it compiled to JavaScript doesn't make it unsafer. All checks happen before compilation. The same for native programs, check happens before compilation, one of the compilation steps is type erasure (unless you use something like Reflections or io validation or pattern matching on boxed values). After type erasure you deal with untyped assembly code. Do you think assembly is more safe than JS? (rhetorical question)
You have to understand where it is impossible: at the I/O boundary where your typed system talks with the outside world. Types help to make sure statically that the typed part of the program does not contain type errors. If the I/O boundaries are clearly delineated, and the data is cleanly marshalled from the untyped world into the typed world, you will clearly see the benefit if the typed world is large. If the only thing you do in your programs is manipulate the untyped data, it is easier without types.
All those folks who are on TypeScript side are biased or at least part of TypeScript living standard . I agree with @Better Coding Academy that TS is scam & will be scam because it takes all its fashion clothing (generics, type checking, etc.) off once transpiled to JavaScript before being compiled into something more of assembly taste . I assume nearly best not too much geeky trade-off for JS lander would be to try C# , of course , this is just my personal opinion .
sounds like you're using too many escape hatches and not qualifying them with runtime type checking too.
A great way to think about typescript is that it will help remind you when your data system isn't as air tight as you think it is.
combine this with a IO typing system like Zod, and you're pretty much gold.
With a very strict configuration, TypeScript is more type safe than C#. In C# a reference type can be null. Not the case in TypeScript. With any language you could read in unknown data. It's no different with TypeScript. Use some assertions.
It may not save you time coding (I'd argue it does - see intellisense), but it π― saves time in prevention of runtime bugs. If you're seeing red squigglies and don't need to fix them to run your app, you're not doing it right.
If you're explicitly typing everything, you're not doing it right. I'd argue that the TypeScript example with context you posted is more readable due to the ability to read exactly what the context is via the generic type parameter.
TypeScript unit tests are usually shorter and superior to JavaScript's due to there being no point to testing a bunch of silly stuff like does this module export a function or not.
I learned that if a type checker just let your app crash "right before a bad access" it is equivalent to untyped.
Lol, no
If it allows incorrect type to pass type check process it is called unsound type system, not untyped.
That's not what I meant.
JS says right before an access on undefined that it is undefined. So the dynamic type check could as well be not there.
This exception itself is dynamic type check
JS type checked it for you and because type mismatched, the only thing it is left to do is "panic" (throw exception)
It's crazy how clueless some people are. What is confusing is they'll sound so sure when they are talking tho. If the language wasn't type checking it wouldn't crash it'd just keep going with wrong values. Dude said might as well just not be there. If I had a number 98, I think is "a" if I used as a char it would say "a" but because it's typed check, it checked to see how I was using it and crashed so I the developer can be informed and correct my mistake or cast it to explicitly tell the run time no I did this on purpose.
Sounds reasonable, thanks.
Got my definition of dynamic typing == untyped from a static typing fan prof. at university.
"Either you use static typing or no typing at all, everything else is BS."
this kind of education. I feel you. I had something similar.
(this is addressed to your professor)
What about IO validation?.. This kind of type checking can be done only at runtime. And all "super" static languages do it at runtime, including such notorious examples as Haskell and OCaml.
I mean even if you use static typing, some checks are impossible to do statically.
Also how to interpret no types? If you would take a look at the parser of almost any language, you would see that parser knows about types. It knows that value in quotes is a string, that value from digits is number, etc. In dynamic languages, there can be no declarations of types of function arguments, but there are always types of values. As well even if type declarations omitted they can be inferred by powerful types systems (to some degree).
What about a gradual type system? Which allows having only some of the types declared.
It's just crazy, I mean I'm sure some of you have worked with JavaScript and feel a bit confident commenting. In my mind I'm like but you see typeerror in JavaScript when you use the wrong type some where or it says type error can't call blah on foo. Then you go on to say it has no types. It's like hearing there was a car crash and being like, I bet you no cars where involve. I just don't get how people say stuff like that. I have a few friends trying to learn programming and they like it's hard man, and I'm like naw people just make it confusing because they say so much nonsense and I don't even understand why. Books and paid online courses are the best route sadly because the internet...
Thank you @stereobooster for mentioning io-ts for strong typing at the boundaries of your application. I really think it helps eliminate all of the problems that Lucas mentioned.
This is indeed possibly interesting forSure:
I am now adicted and dependent to the type sytem... when I do small stuff in JS I always end up changing my extension to .ts because it is way more easy... so the tradeoff you are talking about is exactly waht it is (a trade off) β I am lazy as F'ck so I prefer TypeScript but... it imply that I need to work more so I can relax about the types... The main point is about the information the type brings more than the safety or what else (at leat to me)... if I wasn't lazy and at the same time concerned about safety I would do everything in RUST perhaps...
For me and the devs at my company, Typescript is only partially about the static type checking. The biggest 'win' that Typescript offers is a direct way to communicate and enforce to the other developers how to use the functions and libraries we build. Using strict tsconfig settings and input validation (like @stereobooster mentioned in another comment), there's virtually no way they can implement it incorrectly, unless they force-override the Typescript compiler. The IDE support and integration of Typescript (autocomplete, etc) is also much better than with plain Javascript (at least with the IDEs I've used recently, which are WebStorm and VS Code).
Regarding the example code you gave for the readability argument, you generally wouldn't define interfaces in the same file as your logic. But that may be a necessary React thing, I'm not sure. I work with Vue which has plugins for Typescript class support and decorators, so I generally don't need to define my own interfaces for that stuff.
Perhaps a similar solution exists for React to make working with Typescript easier? The biggest pain point of Typescript is interop with plain JS libraries (especially if they depend on the dynamic nature of Javascript), but most of the bigger libs, tools & frameworks have Typescript support these days (built-in or through the use of plugins like with Vue).
I completely agree with your last point though. No matter which language you use, be it Javascript, Typescript, Scala or Whitespace, following best practices and writing clean, structured code is paramount to a well-working codebase and a good developer experience.
For me this is the biggest win of typescript. Types act as another layer of documentation. It encodes valuable information in the code that helps future developers use what you wrote
As a junior dev on my first job who had to read the code other team members wrote in a project, I can testify to this, TS was a godsend! I was up and running in two days max and able to contribute. The code didn't even have a single comment (that's bad or not is another topic,but I feel with TS you don't need much commenting anyway). Without TS I estimate I would've struggled for a week at least just to understand what was going on. I wasn't sold on TS before, but after this I'm never not using TS in a project. The self documenting aspect of TS is enough to warrant its use in every project, let alone all other benefits.
Thank you for your response! Like I said, there are cases where I think it is appropriate, including:
However, I do personally think it is a hassle, and that there are better ways to communicate coding interfaces across teams and developers. I'd also like to play devil's advocate here; even if you do use TypeScript, an ignorant (or arrogant) enough developer can still make coding standards really hard for your team.
We previously used JSDoc comments with type info, which worked fine and is still a decent solution when working in plain JS because most IDEs understand it just as well as Typescript annotations, but Typescript also lets us enforce it instead of just communicating (we still use JSDoc for documentation). Which ways do you prefer to communicate the information?
Along with a very strict tsconfig, we also have a rather strict set of eslint rules, and an .editorconfig file to cover all bases. Developers have to go out of their way by explicitly disabling all these tools to contribute something that doesn't adhere to our coding standards (and even then it'll still get caught by CI). So at that point you're talking about malice which is a whole other discussion.
We do use coding standards based on our common preferences and opinions, to make 'enforcing' these standards as easy as possible on the devs.
As Jeff Atwood said, the best code is the one that is self-documenting. I follow that rule, and I believe that static typing and JSDoc comments just cement in bad code even further (cause then refactoring it takes even more work).
There are certain patterns that become difficult if not impossible to enforce across a codebase. Not using shotgun surgery, for example. I think regardless of how much CI pipelining you do, ensuring the quality of the codebase still comes down to the skill level of the developers, proactiveness of developers with regard to regular refactoring, and the proactiveness of managers in maintaining code review processes and hence enforcing code quality.
I agree that JSDocs can get stale, but TS types donβt have that same affliction. Do you realize that you donβt have to explicitly create interfaces? Thatβs why Iβm so confused by this point:
TypeScript can infer the return type of a function. So it that manner... TypeScript is the most effective language at creating βcode as documentation.β
For instance everything in this example is standard JS but when itβs run through the TS compiler it catches the error implicitly:
Update: Based on Edwardβs feedback below Iβd like to clarify that you have the option of explicitly defining the return type too (more info here). I personally find it amazing that you can have implicit or explicit return types. Is there another language that allows that?
No. That does NOT make TypeScript the most effective language at creating βcode as documentation.β simply because it can infer returned types from the function, because you can always implicitly return the wrong thing.
And put aside whether liking typescript or not, this is the attitude that leads me to dislike the typescript community. The title says "change my mind", and you are definitely not changing anyone's mind.
Edward, my goal is to help people to get happier at work. For me, part of that happiness equation is TypeScript. If Iβm not being convincing, then please let me know how I can better be of service to the larger community. I want people to understand more. If through that understanding people discover that TypeScript isnβt right for them, then Iβm happy. If they discover that TypeScript is right for them, then Iβm happy too. So please let me know what I can do. Is there a type of problem or example situation that I can illustrate with a code example?
This tone is better, and I appreciate that.
I work across multiple programming languages over years, and I think that every language has its own philosophy and its own way to achieve certain objectives (either it being the best is subjective).
Typescript is one language that I have to work with closely recently. While I appreciate some of the good things TS can bring to developers, I wouldn't say it is one-size-fit-all language for all the practical use cases.
In this particular discussion, I think a elaboration of how you can achieve "code as documentation" with inferred types in TS with some code example would be helpful. (Though I personally thing proper unit tests and JDoc would server better in this particular aspect, and it is not a TS specific thing).
I updated the original comment with examples. I donβt understand the βtoneβ comment though. If youβre reading my comments and assuming that I have some kind emotion behind them, then thatβs a tone that youβre projecting onto it. My goal has always been to spread knowledge and enthusiasm.
As for the testing comment, every professional project Iβve developed recently has over 75% test coverage and it uses TypeScript. Why does everyone bring up testing vs types like theyβre mutually exclusive? I like both. A lot.
I do not think testing and typing are "mutually exclusive". But one of the "pros" people keep pitching about Typescript is the "code as documentation" and "less error" talking point, which I think is already achieved by having proper unit tests whether the language is typed or not.
I could be biased here, but just talking about this specific "merit" Typescript can give is not convincing to me. It could be also due to working style, because I tend to write very thorough unit test coverage (~98% across the projects I developed in the past few years).
Don't feel insulted here.
Imma lead with that.
Every now and then you gotta be like, huh and listen to what people are telling you and learn from it.
I don't wanna sound condescending, I was kinda like that when I was younger too pushing my own thoughts. Honestly, listening is an important skill. Learning is an important skill. Being able to take a step back is an important skill.
There are many things in this post that just plain wrong.
There have been some follow up articles about this post that explain what is wrong about it. Read them. They are not opinions btw. As I said plain wrong.
I really hope you take the time because honestly it's a long post. I know you put time in to get it out and not everyone can sit down and do that.
It means you care which is key to getting to the point where you can do amazing things.
Caring is something you can't teach. You can't inform a person, they just have to have it or not.
Listen, to what people are saying and look at it again, perhaps it will give you some time to think. Perhaps write another post afterwards.
At the end of the day I'd rather a person misinformed than one that doesn't care.
Look into it and then come back, wish you the best on your travels.
Have you ever worked with a piece of JS code and thought any of these?:
I certainly have, and all 3 of these things (not to mention several more) slow me down and annoy me as a JavaScript developer. Oftentimes I would have to dig through 3 (sometimes 5+) files to see where an actual value comes from, and sometimes even it comes from an external service that has little or no documentation about its return types.
In TypeScript - unless you are dealing with
any
s - the problems go away and your IDE or terminal can give you answers to these questions in real-time. Huge productivity boost.That is why I will never again work on a codebase that doesn't leverage static typing.
This.
I have the experience that people that behave like OP in thinking "this is a waste of time tool I prefer raw", usually is people that think their code is a piece of art and there's no imperfection on it, which translates later in a disaster code base.
Have you tried using an IDE that does this for you with JS though?
New developer on our team is trying to convince us to switch to Typescript with arguments like this. He has only ever used VSCode (which is terrible out the box for JS) and was trying to impress me with its intellisense. I then showed him IntelliJ and atom which have been doing the same since before TS was born.
I realise I am now in quite a luxurious environment where we use ES6 modules and current functionality with good IDEs. Many people seem to have written JS 5 years ago and are coming back to Typescript with the impression it's that which has somehow "fixed" JS. Almost all the good benefits boil down to things JS now has / VsCode support.
I am currently loving development with ES20## no build step in dev / Babel . Typescript just adds an unweildy and (IMHO) really bad typing system on top and enforces a build step. They could have at least looked at HindleyβMilner types and languages that use them rather than running with what they have.
I strongly disagree with the article. For me it just looks like a really biased article created just for the sake of having a conversation started (which, comparing the number of likes to the number of comments, it successfully achieves).
Just to enumarate some things that are orders of magnitude faster/better with TypeScript than with plain JS:
1) Refactor code across multiple files.
2) Autocomplete quality.
3) Catch A LOT of errors while you type. The ts strict mode can save you hours of pain and reduce the number "can not read property X of undefined" errors to almost none.
4) For the libraries that come with typings (most of them) you have a much higher chance of using them as intended and always passing the correct parameters. Even if you read the docs, without typings you might pass the parameters in the wrong order, or forget to wrap a variable in an Array.
5) Writing more robust OOP code. Try extending classes, implementing interfaces, having virtual methods and other useful OOP practices in plain JS. Your code will crash a lot at runtime. Yes, you can add checks for abstract classes and implement your own virtual functions, but that doesn't really save time over TypeScript, does it?
It's just like saying you shouldn't use a linter, as it's your job as a programmer to write readable code, research and respect all good practices, while also stating that trying to use any external help to making that happen is bad.
Yes, TypeScript does slow you down if you don't know how to use it and it takes time to learn it, but so does every new language. Once you learn it, it will actually save you time in the long run, not waste time as mentioned in the article.
Saying that typos and other human errors "can generally be caught by an experienced programmer anyways." is like saying a professional athlete never makes mistakes. Yes, it makes them less often, but no human is perfect.
The article also mentions that TypeScript is pretty useless for a senior developer as they can write good code anyway and notice all errors while typing, but I have a strong feeling that the more senior a dev is, the more likely it is that he actually uses TypeScript.
I do think, and if I remember correctly it's also mentioned in the article, that the author never used TypeScript in a medium/large multi-person project, because, once you do, you realize how often you get to think: "wow, if we weren't using TypeScript, fixing those issues would have taken so much time".
this is exactly my opinion! I just wanted to reply to whole article with simple question: is linter also waste of time? but you also covered main points that I strongly agree with.
Brilliant one, Lucas π
It's just so simple:
Wanna write clean code?
Learn how to write "clean code", NOT "static typed code".
Wanna write more reliable code?
Learn how to write tests.
No matter how clean code you write, once you reach certain threshold you'll run into problems with JavaScript. There is a good reason why it's one of the most hated languages, and TypeScript makes working with JavaScript codebase much easier in the long run.
Do you have evidence to back up your claim? My admittedly personal experience with tens of thousands of lines of typed code would lead me to believe otherwise, however I'd love to hear your side of the story!
This is my personal conclusion reading the experiences of more experienced software engineers + my personal experience working on the custom Node.js e-commerce platform.
I believe that, once you reach certain point in the project (I'm not talking about specific number of lines of code nor any other specific metric), dynamic typed language will actually slow you down a bit, because you'll deal with errors which would be eliminated right at the start in strongly typed environments. Of course, I'm not saying that this could be a substitute for following good practices, but it's much easier following good practices in a language which enforces good practices and prevents yoy from making stupid mistakes, like adding number and string. Yes, you should write your code in a manner that won't allow such things to happen that much, but from a personal experience, this is much more easily done in TypeScript, and even though I had to write more code, in the long run it made me more productive.
Nevertheless, I would like to hear your experience from working on huge codebases in JavaScript (or any other dynamic typed language) and the ways in which you addressed such problems. If I had to write enterprise level software my first choices would definitely be static typed languages, and not TypeScript, but if I had to work inside JS ecosystem, I would definitely choose TypeScript for such task.
Lucas, do you have evidence to back up you claim? Historically, speaking most JS engineers I know forget that the code on nome_modules wasn't written by them yet still count it as lines of code.
So it would nice do see your proof, remember you are defending your thesis here.
Here you go blog.acolyer.org/2017/09/19/to-typ...
cc @yaser
I haven't gone through the research paper, and I skimmed the article real quick...
Could please correct me if I'm wrong:
Out of 3 million bugs they picked only 400 and studied them to reach that conclusion, right?
3M is the number of github issues, not all of them bug fixes. Researches were forced to recheck manually if it is a bug fix or not
but they picked enough of them to make sure this is statistically significant result
If you want more researches check this article dev.to/baetheus/thank-you-next-typ...
@stereobooster I wasn't asking for support that type systems finds bugs, I was asking that the author of the article defend any of his points. :p
However, if I were to extrapolate the information from that article it would be that two years ago, when TypeScript was still new and lacking a large following (not many public modules were properly typed back then), it still had a significantly positive impact. If they ran that study again today I would imagine the results to be significantly higher, just from the new features in TypeScript let alone the number of fully typed libraries that now exist in DefinitelyTyped.
Sorry for my late reply, and thanks a lot @stereobooster for the explanation π
Besides that the researcher is a guy from Microsoft (which could make the research a bit biased), and I'm not a math expert.
But the confidence interval is affected by the variation & the sample size.
And, I find 400 bugs to be a ridiculously small sample size and you know that bugs can vary to an infinite interval.
Of course static typing would discover some bugs, but everything comes at a price.
The Price (blind spot that the research is not looking at):
Supposing the numbers were very accurate, Is the extra effort (using static typing) worth it (the discovery of 10% bugs)?
That 10% of bugs, are they really hard to discover bugs? or just ones that you would open the browser and you would find them right away?
Generally, bugs that devs find valuable to discover are the logical ones, not the syntax or statically-typed ones.
Typescript would require you to write more code.
And hey, LOC (lines of code) is a liability, NOT an asset... means that extra code need to be maintained.
I just started a discussion from a different angle here (feel free to join):
Will Typescript Make Your Software Bug Free?
Yaser Al-Najjar γ» Aug 13 '19 γ» 1 min read
Yaser, firstly, there are three co-authors on the 'To type or not to type' paper, and two of them are listed as being at the University College London, and one at Microsoft Research. Now, you could argue that the Microsoft Research guy is pushing TypeScript because some other team in Microsoft makes it. Far-fetched, but sure. So then why would the paper say that both TypeScript and Flow were about equally effective? Flow is made by Facebook. Wouldn't that go against your bias argument?
Well, that's how statistical analysis works. You don't need to trust this paper, calculating a sample size for a statistically-significant result is a well-known technique. Go to surveymonkey.com/mp/sample-size-ca... and plug in the numbers (population size 3 million, confidence level 95%, error margin 5%), you will get the same sample size 385.
Nope, they looked at it.
The extra effort was timeboxed deliberately: they decided to look only at bugs that could be fixed by applying very simple types within a 10-minute window.
These were bugs that were shipped to and reported in production. So they passed all quality-control methods that the projects already had in place.
Unit tests also require you to write more code. That's a liability, don't write unit tests! ;-)
Nikola, my friend...
It's not right to assume that there is some "threshold" without having a solid proof (aka running into one).
Cuz really, tons of companies are doing just fine with the normal JS... not just fine, but actually PERFECTLY FINE.
Even us (Coretabs Academy), we are doing really great with the normal JS, and we super barely have problems.
I mean, before throwing such assumptions about "long-run" and "large codebase", please try it and see how it goes.
Hey Yaser,
I don't know why you think I'm just assuming it - I actually have experience working with a bigger code base written in JavaScript and TypeScript (our front-end part is written in JavaScript, and back-end is in TypeScript).
I doubt anyone can give a specific proof for this and we can all talk from our experiences. As I answered before, this is my experienced combined with the stories I have read on this topic (dynamic vs static / strong typed systems) written by more experienced software engineers and I'm definitely not saying this is something written in rock and I would like to see examples where this is not true.
Right now I'm working on an e-commerce system written in TypeScript. I don't know how much lines of code it has nor I think it's important here. What I can say for sure is that it makes me much more productive to know upfront if there is some potential problem with my code instead of running into problems in runtime. Time which I would have to spend debugging the problem may not be high, but it adds pretty quickly. At the start it took me more time to properly structure my code, but in the long run, I believe I saved much of my time.
I'm not saying that just using JavaScript will bring you the problem - what I'm saying is that bigger, properly structured TypeScript code base will prevent you from running into the problems which could happen to you more often with the same code base written in JavaScript.
As I said before, writing in strong / static typed language is not a substitute for the proper structuring of your code base, but my personal experience is that it's much more productive to write and manage huge code bases in TypeScript than in the JavaScript. If you think otherwise, I would like to hear your experiences on this topic too.
This is from your site.
If members had type
Member[]?
this would have been caught by typescript, and you'd be forced to check whether it was defined.It only took me a minute on your site to find that, what else do you suppose is lurking in there that could've easily been caught pre-runtime?
Thanks Nikola for sharing your view, I really understand what you're saying.
My point of view about TS is that it adds extra code... and from my experience: extra code = more work and more time consumed (no matter how it is).
I always see the LOC as a liability, not an asset.
I saw your GitHub has 17 contributions in the last year (and mostly on non JS code), it's something you might want to change... cuz people do judge on that (sorry for judging too fast).
You just laid your hands on the blind spot that I saw in this whole discussion (from other devs in this topic).
Which is (dynamic vs static) typing langs will solve the problem, it's not.
I believe the whole discussion should be about the architectural & design decisions and the developer expertise.
Yes, you're absolutely right about how TS introduces better design decisions.
I faced exactly the same experience when using C# then Python. I said C# (and ASP Core) tells you exactly how to do things, but Python gives you all the flexibility and power to do things in anyway.
In time, I realized that I finish my projects in Python on time much more faster that what I did on C#!
Why? cuz I transferred that knowledge (of doing things the right way) from C# into a language that allows me to do me doing things in anyway.
And that is ultimate power, and the only catch is as you know:
@maxinertia
Does that affect the end-user in any way (would he see any unexpected result)? NO
Then, do I care? NO
Yaser,
Just because something doesn't affect the user now, doesn't mean it won't affect it later or cause another, seemingly unrelated error.
That was hilarious, you caught him off guard with that bug.
βIt only took me a minute on your site to find that, what else do you suppose is lurking in there that could've easily been caught pre-runtime?β
Hahahahahahaha hahahaha hahaha π these fools with their βTypeScript is not helpfulβ crap. π©I can just imagine how hard it would be to understand their codebase.
...undefined objects during runtime aren't necessarily going to be caught by your static type checker. if the api changes and leaves out that key object, what good did your type system do?
You can write clean code and still find static type checking helpful. These aren't mutually exclusive.
Who said that "they are mutually exclusive"?
I just stressed on focusing on the goal (clean code),
Cuz "static typed code" != clean one
And hey, many people just mix those two!
Typescript enforces better coding practice by design and prevents the kind of crazy stuff you see in JavaScript projects.
If you work in a company with contractors or developers at multiple levels of ability, TS will always increase productivity across the team.
Articles like this usually seem to forget that people are inherently fallible and lazy. TS enforces rules that keep the windows from being broken (to steal the uncle Bob metaphor)
"Typescript enforces better coding practice by design and prevents the kind of crazy stuff you see in JavaScript projects."
I haven't found that to be true tbh - Almost all Typescript projects I have both seen and been a part of seem to follow standard class based organisation. I would argue that Typescript really pushes people down the class route and then they end up with the same old problems with classes we've all had with large codebases and classes.
Now - you can definitely CAN work without classes in TS but if you say it "enforces better coding practice by design" I would have to disagree. It is most definitely not a crutch for inexperience.
Well said. You rewrote my whole article in four lines!
This is called "subjectivism".
If the majority of people thinks that TypeScript is awesome and productive (according to surveys), then so be it, why try to convince people otherwise because you don't agree with it? We don't need to change your mind and neither us.
All the comments in this "article" are just that, subjective, including mine. The only positive thing here is people pointing out good points based on actual data, not assumptions like this article.
A few points you haven't covered:
1) Code refactoring. TypeScript paves the way here. I once refactored some UI code from 1400 lines of typed jQuery to 700 lines of React. I didn't test or even run my code, but I pushed it to a branch and my co-worker pulled it and told me it worked first try and passed all QA. It would have taken much longer to refactor with plain JS, and likely would not have worked first try. From completion in JS, to completion in templates (JSX) to completion in the styles (CSS-in-JS), the refactoring was a total breeze. I have never had such a good time doing major JS refactoring until I used TypeScript.
2) Communication: more than anything, types allow cross-developer communication with nothing but code. Interfaces tell other people what you intend (without them having to open a separate test file for example). It saves time in understanding code. This is important, for future devs coming onto a project (and previous devs leaving).
I think you'll appreciate TS more when you consider those aspects.
You're almost immediately destroying your own arguments - all of them - in just one phrase:
"can generally be caught by an experienced programmer anyways"
So your implication there is that if bugs get through that Typescript would have (trivially) stopped, it's because the programmer isn't experienced enough? It's not the code, it's the developer?
In that case, after 25 years of writing code, I'm not experienced enough by your definition.
Maybe you're too good a programmer to need static typing. Maybe you don't need unit tests, either. Maybe you don't need automated tests. And if you do, perhaps you should take your own advice and "learn to write better code".
But as for myself, I'll take all the help I can get - I might not be experienced by whatever definition you use, and I'll readily agree I can always learn to write better code, but what my experience does tell me is that static typing is useful both to me as a programmer, and also my IDEs and other tooling, which in turn make up for my weaknesses and let me concentrate on providing actual value to actual users.
Just being curious, do you prefer compilation error over run-time error? If the answer is the compilation error, I'll say TypeScript is not that bad.
The thing I found most valuable about TypeScript is I can check error on compilation, the required properties on a type/interface already save me and my team hours of debugging, without a doubt if I need to prevent developer errors, this is my life-saving.
And the second thing, I found is that you can use untyped JS in TypeScript. It gives you the option of
any
and@ts-ignore
. Sometimes, I do this just to code faster, I come back later to fix the problem of TypeScript warnings. So, TypeScript give you the power and also the options.Typescript may not be for you, but what your saying doesn't make any sense. You sound like you work alone more often. I remember getting a snippet of js and not having a clue what was what. I was like console log the variables and send it to me. I remember getting typescript code and instantly knew everything that was going on. So static languages are for static analysis, it's not about run time type checking for typescript.
Typescript makes code readable because it describes the content of the code in the lease possible way, compared to using jsdoc, and typed js has been proven to have less bugs. It's not typing that slows development it's bugs. Look it up
Typing is a great idea, but no implimentation has proved that it works in practice. Typescript is so flawed that it destroy coding experience totally.
From someone who was so annoyed by wrong TS error messages, and had to add too many ts ignore comments
Please see dev.to/codemouse92/comment/e3bp
So TS is always correct and never gives stupid errors? Even TS team doesnt believe so, that's why they have ts-ignore.
Sure, every newbie's code are swamped with simple mistakes, and simply fixing those typos can make the code "run". That gives you the immpression that the compiler is life saver here. And that is ahuge delusion
If you use it properly, it should be very rare to get a 'stupid' error. Almost every type error is saying something interesting, in my experience.
ts-ignore
is not something unique to TypeScript, every language provides escape hatches from their static checks. E.g. Rust'sunsafe
and Haskell'sunsafePerformIO
, etc.First, why are you so sure that I am not using it properly? Is it that difficult to use a compiler "properly"?
Second, great. Thanks for the point. It helps explain why all static language is failing at a certain level.
Cheers
Actually, it kinda is difficult. You have to put in some work to understand the type system, error messages, idioms, how to take maximum advantage of static types and their intersection with dynamic values. No such thing as a free lunch.
Well here's the thing. Static languages have an escape hatch to allow dynamic behaviour. However dynamic languages don't have an 'escape hatch' to allow static behaviour. So really, by sticking to dynamic only, we are limiting ourselves.
Right. Thanks. With your reasoning even eating lunch is difficult, you have to learn which one you have to chew and which one you have to swallow immediately, and how to have both together for maximum eating joy...
Sorry for the sarcarsm, but man, using static type is just the easiest thing in programming ever.
Anyway, goodluck with programming
So it's really easy and it can be helpful ... I don't get it, in that case what's your argument against it?
Did I say it can be helpful? Maybe, for people who cant determine what type of variable he is looking at. But for me, and the author of this article, TS is doing more harm than good. And it is like a pain in the ass using TS every day
Ha ha, OK, best of luck to you as you are obviously a programming superstar who doesn't need any help from a typechecker.
Yeah, sorry if I sound like a jerk, but I had my years with static typing already. At first things are super nice, but then shortcomings start to appear, and now, it totally outweighed the good stuffs.
So yes, typechecking does help here and there, but the tradeoffs are far too big for me. So, no thanks
Some comments may only be visible to logged-in visitors. Sign in to view all comments.