Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: Is TypeScript worth it?
365 points by roberttod on Jan 12, 2023 | hide | past | favorite | 443 comments
I have been using TypeScript for a few years now, and I haven't yet been convinced that I would choose to use it if I had the choice; not just for my own personal projects but for large scale applications where the codebase is shared with many developers.

I want to skip over the static typing benefits argument, because I think it is well understood that static typing is a good thing and if we could bless JavaScript with a built-in and robust typing system then I don't think many people would be against that. My issue is with the amount of extra work it places on developers, much of it the "dumb" kind of work which can eat up hours and doesn't deliver all that much value.

i) Like a framework, you are at the whim of TS devs as it gets updated (edited)

For example, a new package you install can require a new TypesScript version. Once installed, you then may need to update your source code. This can place quite a high tax on the developer, where perhaps a 10 minute change becomes hours long.

ii) Libraries are badly documented

Most libraries do not document their types, or have no examples using TypeScript. Some worst offenders: Apollo, Protobufjs. The type definitions exported by these libraries can be large and complex, and the error messages emitted by TypeScript are so long and cryptic the result is often a drawn out process of trial and error along with trawling through source files.

iii) Error messages are hard to follow

Errors are long and don't provide enough detail. They will explain a type mismatch referencing many types you may not have ever seen, and are not documented anywhere. Except for simple errors, many of them are very hard to follow to a remedy.

iv) It requires yet more transpilation

Transpilation takes time, and always adds a burden to developers. I didn't mind so much with ES6 etc because eventually many functions were included in a broad set of browsers. There doesn't seem to be much progress including TypeScript in a browser, and feels like these complicated transpilation steps could be with us for a long time.

I could probably add more to this list, but my point is that I just can't see that TypeScript is worth all this time investment and making progress so slow sometimes. Are there others that come to this conclusion? I mainly see positive posts about TypeScript.

edit: I referred to TypeScript as a framework which it isn't. However it feels similar to me in that you are at the whim of TypeScript developers and how they decide to progress with the language.




Hi there! I work on the TypeScript team and I respect your feedback. Of course I do think TypeScript is worth it, and I'll try to address some of the points you've raised with my thoughts.

i. Dependency management is indeed frustrating. TypeScript doesn't create a new major version for every more-advanced check. In cases where inference might improve or new analyses are added, we run the risk of affecting existing builds. My best advice on this front is to lock to a specific minor version of TS.

ii. My anecdotal experience is that library documentation could indeed be better; however, that's been the case with JavaScript libraries regardless of types.

iii. Our error messages need to get better - I'm in full agreement with you. Often a concrete repro is a good way to get us thinking. Our error reporting system can often take shortcuts to provide a good error message when we recognize a pattern.

iv. Compilation can be a burden from tooling overhead. For the front-end, it is usually less of a pain since tools like esbuild and swc are making these so much faster and seamless (assuming you're bundling anyway - which is likely if you use npm). For a platform like Node.js, it is admittedly still a bit annoying. You can still use those tools, or you can even use TypeScript for type-checking `.js` files with JSDoc. Long-term, we've been investigating ways to bring type annotations to JavaScript itself and checked by TypeScript - but that might be years away.

I know that these points might not give you back the time you spent working on these issues - but maybe they'll help avoid the same frustrations in the future.

If you have any other thoughts or want to dig into specifics, feel free to reach out at Daniel <dot> MyLastName at Microsoft <dot-com>.


Thanks for your work, TS saves me time every day. I was saying something similar to the op 3-4 years ago but really cannot picture working without some kind of type safety in JS now.


> TS saves me time every day.

Hmm, not my experience. I do TS for years now and still today I'm spending more time on fighting/pleasing TS compared to the actual code.

JS with all its node_modules dependencies is a complete nightmare to get the typing right. I regularly have to change good solid code to please TS, but at the same time TS often doesn't complain when the typing is obviously wrong.

I once started with Assembly, Pascal, C and C++. So please don't start to explain to me what strict typing is and the benefits and so on, I know. JS uses dynamic typing by design. And I remember how awesome it felt when JS came out and we could write code without doing type juggling. And I believe that with type inference and some other tooling in the IDE we really don't need TS at all.


I’m noticing a pattern in your arguments.

You need to understand that I (and I suspect many others) don’t have the same experience as you. I don’t _fight/battle with_ the type system, I work with the type system - and I enjoy it. It saves me countless hours. I don’t actually use javascript without TypeScript anymore - it’s simply not worth _not_ using it - for me.

You ask whether it’s worth using it - and you keep telling people not to explain the primary benefits to you. The answer is yes for many people. It seems like you’re looking to be convinced that it’s worth it but you don’t want anyone to tell you what you already know. I’ve done this myself in the past - I’m not saying the situation is the same for you but it might be worth looking inside at: when I did this it was because I knew that x was worth it but I’d put myself in a position where getting down off my hill and accepting that x was worth it would require me to admit that I’d been wrong about it. Now I could double down on my position that x was simply not worth it, or I could come down slowly and start to enjoy the benefits of x more openly.

If you kinda feel that what I’ve just said might be a factor for you, then that’s already incredibly brave. If you’re interested in taking it further I can recommend role playing: for a week (just a week) role play as someone who thinks x _is_ worth it. Adopt the positions on the benefits that you already know. Act like you love it, act like the type checker REALLY helps you and saves your time, act like the types aren’t all that bad and CAN be used in usefully-constricting ways, and of course, help make your code even more self-documenting. You’ve gotta convincingly act, as if you’re going to win an Oscar. The audience fully believe you’re a true, light-seeing advocate for x.

Being able to change your mind is a great, noble and immensely valuable skill, and I can see that’s what you’re trying to do. Consider role playing as an advocate like I suggested above and perhaps you’ll have a new tool in your toolbox.


> a pattern in your arguments

> You ask whether it’s worth

> you keep telling people

I just want to point out that the account you're replying to isn't the OP.


It sounds you are essentially recommending therapy for those who don't like TS.


SM people enjoy their pain too ;-) Typescript for "Consumer" is great, but as soon as you must write own complex typings, that is everything, but really not a joy.


> I do TS for years now and still today I'm spending more time on fighting/pleasing TS compared to the actual code.

Admittedly, this mirrors my own experience, at least in some cases, which I shall not deny.

Was called in to help with this one particular TypeScript codebase that used React a while back, it was a mess. I suspect that some of the chosen abstractions were overengineered and overcomplicated (and perhaps underdocumented), but at the same time TypeScript made things more finicky and as a result the development velocity tended to be on the lower side of things, when compared to similar projects with JS. This was especially noticeable when new developers needed to be onboarded, though at the very least refactoring could be done with more confidence. Essentially they were not dealing with just sub-optimal code structure/architecture, not just the ever increasing complexity of React, but also how it all integrated with TypeScript on top of that.

It's a bit of a double edged sword, because when done right, TypeScript is objectively better than JS in at least some regards (refactoring for one, the type system obviously but also how well IDEs can figure out autocomplete because of it, or highlight issues that would otherwise manifest at runtime only with JS), however there is also potential for things to get much worse than your typical JS codebase, when done wrong.

This might be a silly comparison, but I'll compare it to something like PHP: when used correctly, you'll get something that lets you iterate pretty fast and just ship stuff, whereas if you go about it the wrong way you'll probably have a badly developed unreadable mess that's full of bugs or security issues, for a variety of reasons. In my experience, TypeScript codebases range from very good to very bad, whereas JS tends to be more mediocre in general, at least in regards to complexity and iteration speed. In regards to maintenance, TypeScript will win in most cases.

Use TypeScript responsibly and you'll have a decent time. Give it to someone who wants to be clever about things and you'll have lots of accidental complexity to deal with, more so than with the alternatives. Then again, personally I think that Angular did TS better than React or Vue, so this might be a niche view in of itself.


Sharing your experience is fine. Rebutting someone saying “this saves me time”, much less in a comment where they’re thanking someone for something they help make, is a bit ridiculous.


> I remember how awesome it felt when JS came out and we could write code without doing type juggling.

You enjoy working with dynamic typing. It more aligns with how you think and program. That's okay!

TypeScript may never be worth it, to you, and that's okay too! Not everyone likes and appreciates static typing.

If you ever do come to the datk side and think TypeScript is worth your time, it will be because that part is not a time waster but a time saver.


> Hmm, not my experience. I do TS for years now and still today I'm spending more time on fighting/pleasing TS compared to the actual code.

What are you doing exactly? I like TS, because it's one of the easiest to use type systems.

I'm also intrigued that you used C++ and think TS is bad, C++ error messages are legendary for being hard to understand.


What's Math.sqrt("hello")?


I use TS daily and I think this sort of argument doesn't give TS the credit it deserves.

Sure, you _could_ use it to check that you aren't making obvious errors like this (but this seems constrained to the "convince me that it's worth it" level of functionality, as it is just a nice-to-have for an existing working pattern).

Where TS shines for me is that it ENABLES new ways of "ad-hoc" coding where it's no longer risky to just create "convenience objects" to represent state when prototyping/refactoring, since you can avoid specifying concrete required types across a load of middle-man code and compose types at each level. This enables the pattern of splatting (composition over inheritance) a bunch of inputs to your data together, and then routing them to the points where they are needed. This scales nicely when you introduce monadic fun (processing some data with children, or something delay-loaded) since your type constraints basically write the boilerplate for you (I'm sure co-pilot will make this even more so in the far future).

There's also the fact that your can have your back-end APIs strongly typed on the front-end via something like GQL or Swagger, and this saves a TON of time for API discoverability.


Or 5/"potato"

In JS it's NaN, in TypeScript (or any other language with a remotely sane type system) it's a compilation error that saves you from running into a random NaN at runtime.


[flagged]


Please make your substantive points without breaking the site guidelines.

https://news.ycombinator.com/newsguidelines.html


What's Math.sqrt(value_from_a_package_that_was_definitely_a_number_before_you_updated_it)?


So then you have to make sure any inputs that get passed into Math.Sqrt aren't strings. You can pay the cost at runtime or compile time, and doing it at compile time saves you headaches later.


I agree that is not a good example, but the exact same thing can happen in more subtle ways that is hard to catch. For instance you might have a function that returns a user. Do you pass in the user ID argument as a string or a number?


>I agree that is not a good example

It's actually a great example, because in JS Math.sqrt("4") returns 2 because of JS's idiotic type coercion rules. So if you're passing in user input and don't typecheck it, it will work fine until someone inputs a letter instead of a number.


You won’t get far with attitude like that.


You know you can just use transpileOnly option and ignore some errors? I use it like that and it’s helpful to model data and speeds up development.


Assembly? No types there, just registers. The only distinction is floating point and non-floating point registers.


If you're just looking for general feedback, constructor typing has made my life really hard trying to type an existing JS library. In a JS object instance like `const user = new User()` you can call `this.constructor.staticMethod()` and it calls `staticMethod()` on `User` or up the inheritance chain. But TS doesn't type `.constructor` so you're out of luck. In the simple case you call `User.staticMethod()` but that doesn't work for an instance method on a superclass that wants to call the method of the constructor of the instance.

I understand why JS makes this difficult to type because you can mess around with the constructor. But for normal every day code you just expect `this.constructor` on an instance of `User` to be `User` and it really sucks that it isn't!


> you can call `this.constructor.staticMethod()` and it calls `staticMethod()` on `User` or up the inheritance chain.

This is where I have come to like typescript. 4 years ago, I would have agreed with you, but TS have moved me into a world where I wouldn't write that kind of code any more, and it honestly makes me sick to look at.

Instead I would just do `User.staticMethod` because this accomplishes several things:

  - super classes shouldn't know about inheriting classes. If they do, TS gives you interfaces and abstract classes for this purpose.
  - it still crawls up the proto chain, so the inheriting class doesn't need to know about every super class
  - no risk in `this` pointing to something unintentional (if someone calls or apply's your method)
  - shorter code, easier to read IMO, especially for less experienced devs


I might agree with you but sometimes we have to type up JS code that is written in different styles to what we'd personally prefer. TS should (a) let me generate the types that are used in JS. There are areas like proxies where that's just not possible, but in this case it feels like there's a disparity between TS and JS over classes. (b) I want to work with this code in my editor without red lines all over the place on perfectly valid code.

super classes don't need to 'know' about the inheriting classes for static inheritance to work. i.e. here is a simplified problem in the library I'm trying to add types to:

superclass:

  static hasField(name) { return false }
  constructor() {
    if(this.constructor.hasField('id')) { ... }
  }
subclass:

  static hasField(name) { if(name === 'id') return true; }
(it doesn't really look like that but you get the idea). That just works in JS, but in TS you get `Property 'hasField' does not exist on type 'Function'`. In the TS definition there are a couple of ways I can trick it to return the right thing for `this.constructor` but if I'm looking at a JS file in vscode with TS' checkJs flag on then this pattern should just work in my opinion.

edit: And I don't think I should have to trick it, that makes the definition harder to read and essentially wrong somehow.


Great of you to hop in. Just want to say that while I can typically navigate error messages in TS, I do occasionally have to do some googling on some error messages (specifically ones around generics that have a super type that apparently doesn’t necessarily agree with a subtype or something — still don’t quite get it), and it’s nice to see that the TS team recognizes the obtuseness of these messages is an issue.


TS#### error messages was a brilliant idea to make them more ~googleable~ bingable at least.


Isn't that pretty standard for compiler error messages? The C# compiler uses CS\d{4} for example. MSVC, MSBuild, various other build tools (at least on the Microsoft side) all use similar patterns with different prefixes.

That being said, it seems like Clang or GCC don't do that at all, which perplexes me a bit. Perhaps it doesn't matter much when error messages are never localized.


I guess TypeScript and C# having Anders Hejlsberg in common probably helps with things like that?


(A bit )off topic - chatGPT managed to infer your email address based on this comment. Required some hints though - most likely due to my lack of experience (first try). I was curious to see how it can improve indexing in general.


Thanks for responding, and thanks for your work for the community! I sometimes place myself in the shoes of devs building TypeScript, especially when I am a little frustrated, and most of the time I realize that a lot of these issues are incredibly hard to solve.

> i. Dependency management is indeed frustrating. TypeScript doesn't create a new major version for every more-advanced check. In cases where inference might improve or new analyses are added, we run the risk of affecting existing builds. My best advice on this front is to lock to a specific minor version of TS.

In my recent case, I needed to update Apollo Server to v4, which needs a newer version of TypeScript (see https://www.apollographql.com/docs/apollo-server/migration#t...), which in turn broke a type used from ProtobufJS. I am still navigating ProtobufJS source code to figure out what is the correct fix here.

> ii. My anecdotal experience is that library documentation could indeed be better; however, that's been the case with JavaScript libraries regardless of types.

Actually I think documentation is almost universally bad, I don't think Go or other languages are that much better (I don't want to wade into that debate though). The thing is, having TypeScript means you need more documentation. Even some pretty well documented JS/TS libraries completely neglect TypeScript and the end effect is that you end up having to guess things, or start reading source code. I don't actually know how you could improve this situation.

> iii. Our error messages need to get better - I'm in full agreement with you. Often a concrete repro is a good way to get us thinking. Our error reporting system can often take shortcuts to provide a good error message when we recognize a pattern.

I will look closer at this and start to think of how it could be better when I see a confusing message. I would probably count this as the biggest area that could yield improvement, because most of the time frustration is born of not being able to understand an error message. Often fixing things lead to trial and error. Can I just open an issue in the TypeScript repo for this sort of thing if I have a concrete suggestion?

> iv. Compilation can be a burden from tooling overhead. For the front-end, it is usually less of a pain since tools like esbuild and swc are making these so much faster and seamless (assuming you're bundling anyway - which is likely if you use npm). For a platform like Node.js, it is admittedly still a bit annoying. You can still use those tools, or you can even use TypeScript for type-checking `.js` files with JSDoc. Long-term, we've been investigating ways to bring type annotations to JavaScript itself and checked by TypeScript - but that might be years away.

Once it is part of the language, that will help a lot :) I considered using Deno or Bun to get me there on the server side, but need to be careful with production services.


Re libraries incompatible with certain typescript versions - e.g. protobufjs fix - it’s been my experience that you want to try and only use compilers specific to each library and compile libraries separately. It’s unfortunate but the JS community often tries to run all JS for a project through the same single compiler tool chain, using one global version of the compiler instead of relying on and effectively linking the JS output for each library. Unless you routinely rewrite third-party libraries to match your toolchain’s expectations, you’re going to have a hard time doing that.

For a library that generates code, that’s a special case, as the code it generates must target a particular language version. You have three choices: 1. Upstream a fix as you propose; 2. Side-by-side install both TS 4.6 and TS 4.7 using workspaces or sub-projects and have some of your code compile with 4.6 and then link the results or 3. Find a replacement that is updated to 4.7. For example, https://github.com/stephenh/ts-proto has 4.7 support listed in its readme.


We do generate the protobuf from a different repo which gets published on npm, and we could generate it for different versions of TS. I suppose all of this work is part of the overhead I am not so happy about using TypeScript.


This is a very interesting idea!


> Actually I think documentation is almost universally bad, I don't think Go or other languages are that much better (I don't want to wade into that debate though). The thing is, having TypeScript means you need more documentation. Even some pretty well documented JS/TS libraries completely neglect TypeScript and the end effect is that you end up having to guess things, or start reading source code. I don't actually know how you could improve this situation.

I think Rust approach is the best one so far, every package published in crates.io has an entry in docs.rs (that is created automatically when you publish your crate in crates.io), so I think Microsoft could improve it for every package published to create an entry in a domain specifically for js docs, if a project does not have it will look empty, but slowly the devs will start adopting it at the point that major libraries will improve the docs compared to what we have today.


> Can I just open an issue in the TypeScript repo for this sort of thing if I have a concrete suggestion?

Yes. There are even issue templates to guide you through writing an issue that the team will be able to address effectively.


>Once it is part of the language, that will help a lot :)

If you want to follow along, the proposal to allow type syntax to be part of JavaScript is here:

https://github.com/tc39/proposal-type-annotations

(To repeat Daniel, there is still a huge amount of work ahead)


> Can I just open an issue in the TypeScript repo for this sort of thing if I have a concrete suggestion?

aozgaa has already answered this one - but yes! If you have a concrete suggestion, that's fair game and we can brainstorm on the issue to think of something. We might not come up with something general enough to implement, but it's often a good seed to plant.

> which in turn broke a type used from ProtobufJS.

I am curious to hear what sort of issue you ran into. Was this the Apollo fork (https://github.com/apollographql/protobuf.js), or the original?


It's the original, which is being compiled on our internal protobuf definitions in a different repository and then installed post compile as an npm module.

I spent a while trying to grok the TS error but started to suspect that it didn't make a lot of sense, so I rm -rf node_modules, reinstalled, and it went away.

It would be hard to figure out what was at fault, but it's probably a combination of the node module system, protobuf, ProtobufJS and TypeScript. I do sometimes get funny type errors and restarting TypeScript makes them go away, in this case I had to go a step further.

I'll let you know if I get this again, or figure out what happened.


I'm old enough to have worked on two different large enterprise applications which predated TypeScript and it was a nightmare.

Personally I've found that JavaScript lends better to a functional style of coding but there are no protections in the language to enforce this and both codebases I saw had a weird mismatched set of object oriented and functional style principals. Defined classes, prototypical inheritance, modifying the prototype chain directly, a factory pattern here, a weird "constructor" there, just figuring out the shape of the data was difficult to do.

The lack of guardrails in JavaScript also empowered people writing "clever" code which technically works but was insanely hard to parse and understand, especially when you're 20 function calls down a stack trying to understand what's happening.

I agree the TypeScript compiler's error messages are confusing but you should have see the types of stack traces JavaScript produces.


I worked many years before TS too and happened to have been working on very neat codebases back then, though I did have the luck of working with a really talented set of people.

I conceed that perhaps you are correct about this - it does force people to write less strange code. JS gives you so much freedom that if you don't keep it simple you can really hang yourself. However if you put care into your code and keep it simple, I don't think TS helps all that much.

There have also been situations where I have had to do something a little bit strange, and TypeScript made it an absolute mess. And if you do enough JS you'll know that sometimes you do need to write a function that needs to leverage dynamic typing pretty hard, even if it's quite rare.


IMO TypeScript nudges you away from bad patterns. If it’s a mess to type it, it’s probably a mess in general.

If you are in a very rare situation and think you know better then there’s “any”, although at that point you really need to think “I’m risking runtime errors and this code is confusing, is it worth it or is there another way?”


> I agree the TypeScript compiler's error messages are confusing but you should have see the types of stack traces JavaScript produces.

Non-transpiled js produces fairly sane and useful stack traces. Its just a shame that non-transpiled js is so rare these days.


They might’ve meant the type errors, rather than runtime errors. TypeScript’s type errors can get flat out unreadable when you’re dealing with moderately complicated types. Even errors with generics can get ugly.

That said, I still love TypeScript


> especially when you're 20 function calls down a stack trying to understand what's happening.

Yeah I hate code like that too, but it's not clear to me how type checking would help.


I think type checking helps with that both directly and indirectly.

It helps directly by making it much easier to know what type or shape everything is. Without types, all you have are variable names and tracing the code back up the stack yourself. Sometimes good naming conventions are enough. More often than not, a variable called `product` can be one of 3 different types and you have no idea why unless you go up the call stack to figure it out.

I find it also helps indirectly by making clever code harder to write. The dynamic nature of JavaScript encourages a degree of cleverness and meta-programming that makes things harder to understand. While you can do the same in TypeScript, making the complier happy makes it much harder to do so, which encourages more straightforward code.

Of course, you can write clever type definitions that are impossible to follow. Sometimes you do want to do some meta-programming without fighting the compiler. But in my experience, the path of least resistance when writing TypeScript is fairly straightforward OOP that tends to lead to clearer code.


> I find it also helps indirectly by making clever code harder to write. The dynamic nature of JavaScript encourages a degree of cleverness and meta-programming that makes things harder to understand. While you can do the same in TypeScript, making the complier happy makes it much harder to do so, which encourages more straightforward code.

Interesting.

Not having to define types makes JS feel very fluid to me when using it to jump into a problem and quickly test out ideas.

You can figure out solutions fast, and I suppose with that power comes irresponsibility for those who don't care to clear up the chaos they are able to leave behind in the fast iterations towards discovering the implementation they seek. In short - it takes discipline, and your argument it seems is that typescript enforces a certain degree of discipline... pros and cons to both.


I just can’t get behind the dynamic typing arguments in the slightest anymore.

It doesn’t take any time to type your code. We’re talking seconds on the hour, and the benefits are huge


It's not necessarily about the time it takes to type the type definitions. static typing leads to developers trying to represent the "real" world in a bunch of categories and arbitrary boxes. Thats not necessarily a good thing because you can loose much time in bike shedding discussions like "Is a person class still a valid person class if it has no Surname" which do not provide actual value to your product. Recommended watch: https://www.youtube.com/watch?v=YR5WdGrpoug


> "Is a person class still a valid person class if it has no Surname"

At least you then know the answer to this while writing code rather than at test time, or worse in prod


You don’t need to do runtime inspection to see what the structure of everything is if it’s well typed which reduces the mental burden when debugging deeply nested problems. You can also be reasonably sure that there isn’t a different call stack with an entirely different structure lurking out there which also helps with confidence in pin pointing problems.


All code has types, even if just implicitly. All typescript does is make sure you are consistent with your own usage.


Because you don't have to use the debugger or mentally map the code all the time to see the (actual) shape of the objects at any point in the call chain?


Nothing prevent you from writing mixed paradigms code with TS as well, you still can mix functional and OOP, factory and direct modification to prototype chain, all that and more..


> I want to skip over the static typing benefits argument, because I think it is well understood that static typing is a good thing and if we could bless JavaScript with a built-in and robust typing system then I don't think many people would be against that. My issue is with the amount of extra work it places on developers, much of it the "dumb" kind of work which can eat up hours and doesn't deliver all that much value.

If I take your question prima facie, then yes it's still worth it, since you seem to be dismissing the main reasons people use TypeScript, the static type benefits, and the bulk of your arguments seem to actually be about how TS can improve, not why one should throw out TS wholesale, which I personally would never do.

In other words, you're focusing on the 20% BS out of the 80% benefits. Can the 20% be improved? Of course, but I'll take 80% benefits over 0% with JS any day.


Doesn't your counter-argument beg the question whether it is indeed 20% BS vs. 80% value? I think the OP is asking about pretty much that percentage. Personally I feel it's more like 70% BS vs. 30% value. Types, after all, are a very weak ontology, i.e., you still cannot know for sure that just because your code compiles it interprets the values it's getting from other party's code correctly. I would even argue that it may create a false sense of safety -- just think of the Mars satellite that crashed because some developer thought a number was in imperial units when, of course, it was in SI.


You need to parse and/or validate any external input before you declare that a variable or field is a certain type, as you probably should be doing without Typescript anyway. Being strict in what you accept and ensuring that you're not lying to the type checker solves the vast majority of these types of issues.

It's been a few years since I worked with TS professionally, but at least at the time, I saw it as 95% value, 5% BS. It provides such plainly obvious value in my eyes that I've decided I'll never write JS again unless it's a single file script or a small throwaway project/PoC.


In my experience, even the one file scripts eventually get converted to Typescript when I realize I cannot specify my types :)


Come on, the OP literally said:

> I want to skip over the static typing benefits argument, because I think it is well understood that static typing is a good thing

The OP is interesting in talking about how much of a pain in the ass TS tooling is, and... it's fair to say it's annoying.

If you accept that static types are good (and the OP explicitly said they do), then what are going to do? Basically the OP is saying, "I want static types but not the TSC compiler or ecosystem"; well... it sucks, but you're never going to get that.

The comment you're replying to is just saying: "Well, if you want static types, you gotta live with the bad stuff".

> Doesn't your counter-argument beg the question whether it is indeed 20% BS vs. 80% value?

Nope.


Let me clarify - I pretty much agree with what the parent says - "it's more like 70% BS vs. 30% value".

I do still want that value i.e. static typing, but as you point out I can't get that without the BS. And so I would rather have no typing which is the only other option (except using a different language).


> And so I would rather have no typing which is the only other option (except using a different language).

This part is what is so wild to me. I simply cannot imagine throwing the baby out with the bathwater, so to speak, to throw out the entirety of static typing just because of the BS around it. In my experience, static typing is superlative, it would have to be some extremely rare situation for me to give it up.


I spent 6 years programming production JS delivered to millions of people before I went to TS and it just wasn't that bad. The code was clean, and the team didn't ship many bugs - this was for a big frontend and ~12 microservices.

Webpack added a lot of overhead - but if you know what came before it, it was a godsend. React added a super complex library, vs Backbone which was only a few hundred lines of code but React is totally worth it.

I'm not just trying to hark back to "the good old days", I think the ecosystem is a big improvement from where it came from but I just haven't seen enough benefit from TS for all the work you need to put in.


We have that in the form of ReScript.


Types help prevent a narrow class of errors. They also help with refactoring. They help avoid messy checks getting in the middle of your business logic. All of this is more than enough to justify using them.

Types do not replace other checks and tests.

I don't think the Mars satellite crashed because they trusted the type system.


> Types, after all, are a very weak ontology, i.e., you still cannot know for sure that just because your code compiles it interprets the values it's getting from other party's code correctly.

This again seems to be throwing the baby out with the bath water. Just because in some cases types can't be verified does not mean we should fully be without types at all. There are a myriad of ways to mitigate even this, Parse, Don't Validate comes to mind [0]. Type Driven Development is another way [1], as well as using runtime type checkers like Zod. This article by Kent C Dodds is a really good example of the latter, it covers everything you're talking about regarding unknown types [2].

> I would even argue that it may create a false sense of safety -- just think of the Mars satellite that crashed because some developer thought a number was in imperial units when, of course, it was in SI.

Actually, that sounds to me like just the opposite case. The dev thought it was in imperial units because they might not have known the type of said number. If the number was instead typed with `ImperialUnit unit = ...`, that issue might not have occurred. Now, if the unit value was inputted incorrectly by the programmer, that's a different issue, no amount of typing will fix a business logic typo. As well, if the satellite was fully untyped, issues like these would have occurred far more often, so taking a singular example as a damnation of an entire paradigm doesn't really work.

[0] https://news.ycombinator.com/item?id=27639890

[1] https://blog.ploeh.dk/2015/08/10/type-driven-development/

[2] https://www.epicweb.dev/fully-typed-web-apps


I like TS for the completions and the documentation. I know OP was complaining lack of documentation but knowing what properties a giant object takes, even if those props don't have doc-comments, is still wonderful.

What I've been doing is, whenever I'm handed a random JSON blob, I throw it into a JSON->TS interface converter, paste that back into my project, and I never have to question what the heck the server is returning to me again.


> In other words, you're focusing on the 20% BS out of the 80% benefits. Can the 20% be improved? Of course, but I'll take 80% benefits over 0% with JS any day.

There are other alternatives outside typescript and javascript, especially for serverside development.


Serverside, sure, I'll agree with you there (I use Rust for my backends).

Clientside, I've tried a lot of compile-to-JS or WASM languages and frameworks. They're just not there yet, especially when you run into some compatibility problems, not to even mention library support on the frontend. The reason I like TS for frontend is it's just JS at the end of the day, you can strip out all of the types and it works. Therefore, things like compatibility issues are simply...nonexistent.


I've been working with JavaScript for 20 years. And 5 years with TypeScript. And, well. I still am not convinced.

Too much overhead for me. I really dislike typing obvious things and boilerplate. Probably my fluency with JS is to blame. I don't need to see types and autocompletion. If I really need to — I just go to the source and inspect the source code, that is how I familiarise myself with the interface. I also think this makes one a better developer.


I think stuff like this really comes down to getting used to and accepting.

I had the same views on code prettiers. I thought, aligning your code by hand makes you think about the structure. That you'd invest more time in making your code readable and thus it would be more readable.

When I first got to use prettier on a team and accepted it's value, the benefits I perceived were so vast, that my arguments seemed irrelevant in comparison.


Sure! I want prettier for types. So I don't have to manually type the obvious things. The IDEs are smart, but I haven't found one that would be that smart.


I'm wondering what do you mean by obvious things, do you have any example? TypeScript can infer types[0] even through context, and it's even a good practice to let TypeScript do that for you.

[0]: https://www.typescriptlang.org/docs/handbook/type-inference....


but wouldn't the static code analysis complain in that example?

at least once you want to do anything meaningful with that x


IntelliJ / WebStorm has this exact feature.

You can also generate API types based on your backend.


That is cool. Will try that. But the type information the IDE provides to me is sufficient even without TypeScript. So, back again to the question — is TypeScript worth it?


I had the same question initially. TypeScript is the way you configure intellisense. Some types can be inferred, but not all, and most of the typing I do is to _restrict_ what data can be used. TS gives you feedback anywhere you ask for it, and paired with IntelliJ I feel like I have superpowers.

Another point: You can create types for your API client programatically, meaning your front-end can be aware of exactly what types your backend is returning. This cannot be accomplished with intellisense.


Let's think about what happens on a team: If a single person goes and reads the source code to learn how the public API works instead of simply using the exported types, that's a wasted thirty minutes instead of two - okay, fine, whatever. If all of my engineers have to do this, suddenly each of them is spending that amount individually; and just like that, we've wasted an entire man-day, for nothing.

As you declared in your own comment, TypeScript is great for reading, hard for writing. I don't know about you, but my code is read several times more often, and by different people, than written. TypeScript is a no-brainer, time-saving wise.


I am a strong believer that every developer on a team should know how the code works. Emphasis on HOW. You only know that if you go to the source of truth. That is how people become proficient with a skill — by doing and re-doing and re-doing things.

I disagree that it's wasted time. The time spent investigating how a piece of code works is time extremely well spent.

If the code is too difficult to understand — of course one can hind behind types.

So, yeah, to sum it up — I think types are an overhead for a well written piece of code.


If the codebase is small and owned by a few people then it might be true. But when the codebase gets large enough and worked on by multiple teams - it is unreasonable to expect that everyone will understand the workings of the whole application.


I don't agree that typescript makes writing code hard. I believe the opposite- it makes writing code easier. Editor integrations are a godsend, even the minor things like auto-imports makes writing code easier.

More functionally, I also find Typescript's type refinement to help make sure I'm properly using the data and understand the state of it after I've done some checks.


How big is the team that you work with ? The benefit really shines in a large project with lots of devs.


I've also been working in JavaScript for 20 years and TypeScript for 5. You will have to claw TypeScript out of my cold, dead hands. You shouldn't need to type obvious things in most cases, TS should be able to infer it. In my experience TypeScript has prevented many bugs, makes coding more enjoyable, clear and faster, and best of all, refactoring becomes like a super power. I've yet to do a large refactor in a good TS codebase that caused a single regression. The word "good" here is a pretty strong caveat though. TS is only as good as you make it, and overlaying types onto a dynamically typed language (especially manually) can cause issues for sure.


You should try out something like Rescript then. It uses the ocaml type system including its ability to infer all types. You get all the benefits of the compiler enforcing consistent usage of types without having to annotate everything.


When you use TS purely for annotating strings and generic Record<string, any> types, sure. What's the point.

Why don't exhaustive matches, unions, and data modelling not get mentioned more often? That's where the true strength lies.


Those are the things I want to use TypeScript for, but it often requires me to adopt the whole ecosystem. I want a middle ground solution; I really just want JavaScript with some parts of TypeScript.


I feel like my JS skills are way above average so I agree with you that if you have the chops then typing obvious stuff just wastes time. However, new developers or those unfamiliar with the ins and outs of JS need help to understand what are they working with. I also feel when a project gets really big/complicated then TS starts to help convey data structures but I think at that point TS becomes the documentation you should have been writing all along. However, the one thing I really don't enjoy about TS is when some library is typed it'll be very strict to the point that valid JS isn't allowed and the invocation of telling TS not to check needs to added for the segment which in turn looks like a code smell. Or the types get to meta-program oriented and I have to start inserting types everywhere instead of them being inferred.


I guess this comes down to personal preference. For me, this is mixing the interface with the implementation. You shouldn't need to know how something works to be able to use it, for me, that's the real overhead. Maybe this works on a small scale, but what if the source code changes?

That being said, I do like inspecting the source from time to understand it better, or make up for missing documentation. Sometimes though, with this being JS, I wish that I could unsee the things that I've seen, code that production depends upon, deep within the dependency tree.

I agree with the idea of fluency when writing without types, but for me it's not about how fast you can write code. Code for me is a lot of rereading and understanding what the hell you wrote just a few days ago, I find typed code easier to get back into and it's faster to find things that broke in parts of the codebase that you're less familiar with when you change something.


"typing obvious things and boilerplate"

That was the center of reservations against TS until I figured out that it's the wrong way of using it. Normally you very rarely have primitive type annotations, or any kind of obvious things, because that's inferable.


"I also think this makes one a better developer."

It's a glorified way to put "slowing you down". When you go to your root store key and think about a better name, a single rename action traces all the usages _safely_ down throughout the whole codebase, across packages in a workspace; now compare that with the manual process. No, search & replace doesn't come close to this convenience. Having this kind of refactoring ability at hand makes you speedier, flexible, adaptive, exploring new ideas, and it makes work fun - these in fact makes one a better developer.


By the way, now that I think about it, I could draw a parallel here, remembering another recent thread here on HN: - TypeScript is easy for reading but hard for writing code - Tailwind is easy for writing but hard for reading code


> obvious things

Obvious things may not look obvious from other programmers or for yourself sometime in the future or from a code you'd written while feeling asleep.

If you'd totally think that's an obvious overhead, just give it "any". Though I never use it.

Automatic type mismatch warning and auto completion in the editor feels quite worth the little "documentation" static typing effort.

Of course, if anyone is using some basic editors that don't even highlight TS errors in real time, then it feels like a complete waste of time.


For me, it's the tsConfig part, it gets more and more complicated, especially when you work with monorepos, the lack of full config examples in the official doc, they just give you properties and explanation, you have to mix and match to get it right.


As i said before, a lot of people expect that writing typescript is as easy as writing js, which is not. I estimate the typescript tax to be around 40-100% more time, especially if you want to do typescript right and not use `any` all over the place. And besides, typescript is a poor fit for someone who is used to writing highly dynamic, lambda based code, which is one of the main niceities of js. My guess is that a lot of people with a background in java and c# found themselves writing server side js and were really unconfortable with this paradigm, so they tried again to turn js into what they knew best - an imperative object oriented programming language. Now, i'm not saying that types are a bad thing, i for one like typescript especially in projects with a lot of people, but, it's funny to see new people struggling to finish a task that should take a few hours in days.


These estimations are pure imagination. I doubt you have `any` real data to support it. Also, that is not the reason why Typescript was created, nor the reason why people adopt it, not even what Typescript really is. Today, almost every Node.js framework supports Typescript out of the box. I challenge you to provide a modern framework that doesn't provide types. And this is not an opinion, nor it is wishful thinking, it is a fact: type checking and strongly typed languages will take over almost every modern software development paradigm.


I work with typescript everyday. I review prs, i mentor junior devs that are learning typescript. Ofcourse this is my experience, maybe yours is different, if so please tell me about it. The only thing i said is that there is an upfront cost in velocity that people are usually not considering when they are choosing to use ts over js. Sure, that cost may be amortised in fewer bugs and easier collaboration across large development teams. But i see people struggling everyday with specifying correct and complete types. I reject prs, i babysit devs that can't figure out how to type certain code constructs. And if i don't do this the project ends up a mess of anys and ts-ignores which undermines the value proposition of typescript.


I think whatever tax you pay in writing typescript (which, as someone reasonably experienced with it, I believe is none or exceptionally minimal) you easily get back from improved efficiencies of not requiring memorizing the entire shape of your application, looking up in seperate documentation, or a run/inspect/write-code just to see what things are.

I think that typescript's type refinement is extremley useful to know whether you've covered all the cases for the types of data as it flows through your system.


If someone cannot reason about types when forced to, I wouldn't want to see their code _without_ typescript.


> These estimations are pure imagination

There are decades of literature on the matter.

You simply have to look for it.

Statically typed languages are known to lead to slower initial development times, because languages are inherently more complex and there are more concepts to grasp.

usually thy also need to be compiled, which makes times even longer and setups harder.

Good news is that long term they tend to be associated with easier maintenance, but it's not totally clear if it's due to static types or the team getting more accustomed to the code base and tools having more metadata to help the programmer.

One thing that is unquestionable it's that statically typed languages scale better in large teams.

if anything goes well, of course , if you OTOH happen to end up working in places where they use types to build gigantic taxonomies, all the advantages are gone.

> Today, almost every Node.js framework supports Typescript out of the box

it doesn't follow that TS is great though.

It simply says that people building frameworks want to sell them to the larger audience possible.

If they could support Java or C++ or Rust, they would.

Many Java libraries or frameworks still support Java 8, doesn't mean Java 8 is the greatest Java out there.


> Statically typed languages are known to lead to slower initial > development times

I hear people saying that, but I'm not sure I buy it. Is there any research that supports that, and if so, for which languages? Also, what does "initial development" mean here? The first day, week, month, year? And unless your project is trivial, isn't it somewhat important that as much of the initial work as possible provides a solid foundation for the future of the project so it wouldn't pay off skimping on this?


PDF: https://www.ics.uci.edu/~jajones/INF102-S18/readings/23_hane...

see conclusions

intuitively static typing is less forgiving and forces programmers to write code in a specific form

think how much time has been wasted writing Java boilerplate code.


To be honest, that looked a bit thin. And the most productivity-killing Java boilerplate is hardly due to its static typing but rather the baroque style required by lots of frameworks. It is important to differentiate between language and how people tend to use it.


I converted a few codebases from JS to TS and this takes a surprising amount of time. I won't put out estimates but it's definitely non trivial.

> I challenge you to provide a modern framework that doesn't provide types

Ruby on Rails


He was clearly talking about nodejs frameworks.


An estimation doesn't need data. It's a best guess. I don't think its fair to call it an imagination. As far as we know that's what he thinks based off his observations.


Strongly typed languages already did take over the software development paradigm. It happened when Java, C++ and C were the dominant languages. Then it regressed back to dynamically typed languages as ruby, php, python and js skyrocketed into popularity.

With the advent of typescript and other things like it... types are now back in vogue but for how long?

The universe is a four dimensional loop. Programming, like history, like life, moves in an endless flat circle. It's all so predictable... Because This ENTIRE thread represents a precursor to the inevitable and impending oscillation back to the beginning of the circle. Types will fall out of vogue and history will repeat.


> types are now back in vogue but for how long?

Probably until startups and organizations that use more flexible languages race past those who strongly type things. Just like in the early days of the web and actually for ~2 decades in which everyone who used loosely typed languages raced past those who strongly typed stuff due to the ease of use and flexibility. If typing was the way to go, already existing typed languages would rule the roost. But they didn't.

The end users dont care about any engineering concerns that we have. They care whether they can do what they want with an app or service. And organizations that can ship code fast will keep their strong advantage.


> Strongly typed languages already did take over the software development paradigm. It happened when Java, C++ and C were the dominant languages.

C is not a strongly typed language. Did you mean statically typed?


It's definitely "harder" to write TS in the sense that you have to learn more stuff and think about things more, but I seriously doubt it is any slower on anything except the smallest projects.

Any time you lose writing type hints you gain back from better IDE support and fewer bugs.

It's really a no brainer. I can only assume everyone here arguing against it works on one-man projects using Notepad.


I share your feelings. These times, whenever I'm setting up a new TS project, feel like:

1) Look up "this months current way of doing things"

2) have a couple of horrible hours wrestling with tooling and the module system

3) add a new feature, install 1 lib with 30 deps

4) figure out that one dep does not work with TS/the chosen module system/whatever versioning related thing

5) go for a walk. scream into the void. come back to the desk.

6) browse through dozens of Github issues to figure out what is going on

7) decide to fork the according dep knowing that I'll hate myself in 3 months

8) ...

Yeah, so I'm kind of missing the good old YOLO JS times w/o semi-colons and stuff. But I need to say that I'm usually not opting for NodeJS for deep "OOP-alike" Domains. I think NodeJS' sweet spot is infrastructural things, MQ Consumers, glue code or little http fetching/posting orchestration scripts. I never had too many issues without static typing because I intentionally kept things simple, had tests and rolled out updates consciously watching the ongoings.


This is exactly my experience. I think TypeScript is an amazing feat of engineering and one of the best typing systems in existence today, largely because it has to describe such an insane set of hacks common in the JavaScript ecosystem. TypeScript has contributed immensely to the theory of programming languages.

But the tooling and the ecosystem are nightmarish! It's skin-crawlingly awful to set up a new project, or to update anything, or add any dependency. This is not TypeScript's fault; not really. But literally everything from the IDEs to the package manager to the output messages are awful. I can even add to your list:

8) ignore hundreds of lines of SEVERE SECURITY ISSUES because literally all of them are false positives all the time

9) deal with Visual Studio constantly crashing, throwing up 600 "build errors" because it doesn't like the standard DOM typing definitions

10) struggle for days to compile and package all the TypeScript files into a re-usable library; give up, and instead set up a script to literally copy the raw *.ts files around.


This is exactly what I struggle a lot with. I just want JavaScript with simple type checking. TypeScript goes way overboard. I also hate TypeScript decorators. I've seen that grossly abused in codebases that just drive my insane.


Maybe we should just jump to a different timeline in which Facebook's Flow won the war against TS


That would have been the best outcome IMO.


I think Typescript isn't worth using, and I find this unfortunate. The Typescript team clearly has put years of work into this, and clearly has tried to shore up the deficiencies in Javascript.

Are you writing a brand-new codebase that needs to work on multiple platforms, and not exclusively in a browser? Don't use Typescript, use a language with native WASM support. This includes avoiding solutions that involve Electron, Deno, and CEF, as they are browsers, too.

Are you writing a brand-new codebase that only works in the browser? Learn how to use HTML and CSS correctly, avoid as much Javascript and Typescript as possible: Less is more.

Are you maintaining an existing codebase with extensive Javascript, and you are not willing to rewrite entirely Typescript? Try using Typescript, but you're better off jumping ship, nothing can save it now.

Any codebase that has untyped code in it, that cannot be compile-time analyzed for safety, that requires a significant client-side investment (ie, a giant blob sent to the browser), is kinda doomed to failure, and you will not realize the magnitude of your mistake until it is too late.

I realize my opinion is unpopular, as the programmers on HN seem to be a lot of front-end devs and a lot of "fullstack" devs, where the "full" is JS+TS in NodeJS, using some predefined popular NodeJS framework. I just want systems that are designed to minimize the BS, I've chased enough BS in my lifetime, TS can never deliver a no-BS system to me.


> Are you writing a brand-new codebase that only works in the browser? Learn how to use HTML and CSS correctly, avoid as much Javascript and Typescript as possible: Less is more.

It's really difficult to construct a comprehensive SPA without a nice framework such as Vue or React; and as it relates to your prior paragraph about WASM, I'd love to take this advice, but reactive UI frameworks suitable for browser are young and immature compared to Vue and React (IMO).

I would LOVE to use a different language and compile to WASM, just don't think I can replace my Vue+TS frontends at this time.


I think its good to bring up SPAs in this context: fundamentally, they shouldn't exist, and you're using the browser wrong. They are the poster child of design smell when it comes to "web apps".

Do you need SEO to work, even though Google Search torpedoed effective SEO a long time ago? Search engines disfavor websites that are extremely opaque and are made of a single page or few pages.

Do you need to be able to open content in new tabs, thus increasing productivity dramatically? Many SPAs will forget the app state and be unable to navigate back to where you were if you open it in a new tab. This also means you can't bookmark them either, and I've also seen browser tab/window restoration screw over SPA state.

Do you want browser performance? Using complex JS/TS to mangle the DOM and causing redraws outside of the initial page load is a good way to scare users off when their browser shits itself for 3+ seconds.


> I think its good to bring up SPAs in this context: fundamentally, they shouldn't exist, and you're using the browser wrong. They are the poster child of design smell when it comes to "web apps".

So a universal, cross platform, cross device, responsive, accessible UI stack that has simple distribution, avoids walled gardens and has excellent performance is a "design smell"?

> Do you need SEO to work, even though Google Search torpedoed effective SEO a long time ago? Search engines disfavor websites that are extremely opaque and are made of a single page or few pages.

Nope. I develop PWAs for healthcare and other industries. I rarely, if ever care about SEO. If I did, I agree that SPA is a poor choice, but for 99% of what I develop, the web app is a replacement for a desktop or mobile application. SEO isn't relevant.

> Do you need to be able to open content in new tabs, thus increasing productivity dramatically? Many SPAs will forget the app state and be unable to navigate back to where you were if you open it in a new tab. This also means you can't bookmark them either, and I've also seen browser tab/window restoration screw over SPA state.

Deep linking has been a solved problem for so long, it honestly makes me wonder why people keep bringing this up. Use a decent router. IMHO this is much easier to do in a web app than a native mobile app.

> Do you want browser performance? Using complex JS/TS to mangle the DOM and causing redraws outside of the initial page load is a good way to scare users off when their browser shits itself for 3+ seconds.

I'm not sure how you're developing web applications, or what stack you're using, but if you're seeing 3+ second DOM mutations I can tell you that you're doing something very wrong.

Web browsers are fantastically performant, I can't think of any other rendering stack that gives you so much capability with such performance.

There's a reason why XUL, Silverlight, Flex, XAML and all the others have disappeared or have such tiny market share compared to HTML + CSS.

The web has fantastic deployment and update capabilities coupled with a powerful rendering layer. It's easy to see why it's a popular choice for application development.


I agree someone is doing something wrong, wrt sluggish browser performance and routing. However, I keep being exposed to this in random SPAs I get exposed to; I can only conclude this continues to be a problem that developers have and the popular frameworks somehow footgun them into this.


They can footgun just as hard with server-side rendering, including breaking when you try to have multiple tabs of the same site.


This is all outdated thinking now that we have PESPA frameworks


I mostly agree with this, and haven't been happy developing JS for some time. I don't enjoy having to deal with bundles, webpack, TypeScript, bloated dependency graphs.

Luckily I can use Go for new projects, and even when picking it up at first I quickly found it more pleasurable to use than NodeJS. I don't JS on the backend if I can avoid it.

On the frontend, I would still argue on balance SPA/bundling is the best option when your company is developing an application. I appreciate that for many things HTML/CSS with minimal JS works well, but for anything dynamic where you have a team of devs, the community and dependencies around React are too useful to replace with much else.


Although I agree with you, I'm curious how this translates to your full time job (assuming you have one)?

I find most companies don't do JS any more (TS experience is a requirement)


Where I work, everything on the frontend is TypeScript, everything Nodejs is TypeScript. I did create a nice little bash utility using Standard style i.e. vanilla js in Node and that's worked out well.

Although I'm senior enough to start a new project without TS within my team, I think it would be a little egotistic. Although I am not convinced by TS benefits, most people at my company are convinced it's necessary and I don't think it's worth going against the grain. There's many more important decisions when starting a new project, and I think the architecture is much more important than whether to type or not. Besides, I now choose to use Go on anything server side, and try to shy away from the frontend because I don't find it as fun to code as I used to (partly because of things like TS, partly because the kind of work doesn't feel as engaging, and feels like busywork).

I worked at a company previously that had a large NodeJS codebase that was largely created before TypeScript was so popular. That's what I mostly have to compare against, and so I do know what it is like to do massive projects with many people without TypeScript. I don't think we ever felt the need for types, and building and pushing code was always simple and safe.


I get what you mean about BS. For me the most painful thing (JS or TS) is if you leave a project for a year you need to use a newer node for security, you need to upgrade modules for security, and some NPM package creators love to have breaking changes or even pull modules completely, forcing a lot of manual work and refactoring to fix.

Whereas in .Net this churn rate is way slower because almost all functionality is provided by the famously backward-compat friendly MS which also sets the culture for Nuget publishers too.


I won't defend TypeScript. Mainly because I'm not interested in doing such a thing; I don't like it that much, clearly not enough to care.

But even so, I will say a couple of things about your arguments.

Regarding i), no, it's not a framework. But then again, I don't think that's what your argument expresses anyway. You seem to be saying "it's yet another dependency you need to keep up with". This would be correct and a valid argument. But it's unrelated with "being a framework" (which, again, it is not).

As for ii)... I'm afraid this argument could be valid for any large group you want to pick in software. Are you arguing JS libraries at large are better documented? Sounds highly dubious. From a different angle, is this a problem with the language itself or is it a problem with the libraries?

Finally, regarding iv), there is no "progress including TypeScript in a browser" and you should never have expected it. Not saying it will never happen because some person somewhere might do it, but you shouldn't expect it.


Regarding iv), I disagree that one should not expect this to happen. There's a stage 1 ES proposal for allowing TS-like syntax in the browser: https://github.com/tc39/proposal-type-annotations So there's good reason to believe this may actually happen in the next couple of years.


Everyone (including the authors of the Type Annotations proposal) seem to be on the same page that static typing - "including TypeScript in a browser" - is not desirable and will not happen.

For the avoidance of doubt, the Type Annotations proposal is not actually static typing, but just a 'fancy comments' for the JS interpreter to completely ignore.


> From a different angle, is this a problem with the language itself or is it a problem with the libraries?

It's a problem for me - the developer. From my viewpoint I don't really care where the responsibility of bad documentation lies, only that it makes me not want to use TypeScript.

> Are you arguing JS libraries at large are better documented? Sounds highly dubious.

You can't really decouple JS libraries from TS. Most JS libraries still maintained support TS these days. My point is that many of them are still documented using JS with JS examples, and don't fully document the types that go along with all their methods.


> You can't really decouple JS libraries from TS. Most JS libraries still maintained support TS these days. My point is that many of them are still documented using JS with JS examples, and don't fully document the types that go along with all their methods.

Ok, but... what you're saying here is that, while you're not convinced by TS yourself, you expect all JS library creators to be convinced. Why should they be?


I am not saying I expect them to be better documented, only that the reality is that they are not well documented in TS and that makes TS difficult to use.


I worked in two different team in two different companies where a full rewrite of the core system was done in typescript.

The technology itself had few issues like compilation time and inability to run the application locally because of reasons.

The new systems were so complicated that everything ended in neverending bike shedding.

The people pushing for "everything to be written in typescript including other teams tooling (aka pulumi)" were very unflexible crowd.

The previous system had few issues that could be solved with database indices.

It's soul crushing to work on these type of places where technology is used for the sake of technology instead of bringing some business value.


These don't sound like they have much to do with Typescript itself, but just the hell of rewriting a project.


> were a very inflexible crowd

Yes because Typescript is so obviously good. It's like saying "the pro-seatbelt people are a very inflexible crowd". Well duh!

Typescript compile time is not great but you can set things up so it doesn't block running (i.e. you ignore errors until you want to fix them). There's no issue with running Typescript locally.

> It's soul crushing...

It's soul crushing to work with people who don't want to do things properly. Endless string and duck tape (aka bash and python) and fighting fragile tools.


https://www.youtube.com/watch?v=YR5WdGrpoug Static typing is not "obviously good" The comparison is flawed. There are no advantages to driving without a seatbelt, but there are pros and cons to dynamic typing.


Is it worth it compared to what? Plain JS? Transpilation from a different language? Rust? Growing apples?

I have used plain JS, GWT, and TypeScript. TS is an incredible improvement over the two others. The TS type system is excellent, very expressive and helpful. An important advantage you get from static typing is that your IDE has more information to work with and so becomes more powerful. If you code in a text editor, you won't reap the full benefits, and you'll have to do more of the grunt work yourself.


try out dart, its much better than TS


How is it objectively "better"? This depends on context. I am sure Dart is worse given a specific condition. I'm not bashing dart, but you cannot say that "A is better than B" without any sort of context to the statement. It's like saying "apples are better than oranges".


Dart is better in most respects. The standard library is light years ahead of JS's, the Dart tooling is fantastic, it has sound typing.

There are a couple of features that I miss from Typescript: the biggest by far is tagged unions.

But I would still pick Typescript for a web project for two reasons:

* The community is like 1000x bigger. Even though a lot of it produces extremely low quality code, there's still a lot more solid JS libraries than Dart ones.

* Debugging is slightly easier since the compiled JS code is essentially identical to you TS code. Chrome has pretty great support for Dart, but if you ever have to delve into the generated JS it is quite painful.


much less overhead setting it up, it can be both interpreted and compiled. Troubleshooting errors in dart is a much more pleasant experience compared to Typescript. Transpiled languages like Typescript has given me so much trouble over the years at work.


Not that TypeScript doesn't have it's pain points but having tried Dart on an Android application recently, there are so many things I dislike about the language and it's ecosystem compared to modern TS/JS. I feel like it would have been a lot better than JS when it came out but now it's painful to use in comparison.

Definitely my preferred route for building mobile apps now though.


I now actually prefer Dart for services and glue code on the backend. I'm so tired of dependabot yelling at me about my hobby projects every week that have yet another vulerability in one of their million dependancies. In Dart I make do with just a handful of deps, then build a binary and call it a day. I tried using Deno with TS, but binaries it generated where absurdly big, 70-100MB depending on the target platform. Also, Deno's --allow-X thing becomes tedious after a while.


Is Dart object oriented language? What is its roadmap? I know it was created by Google, but is it replacing js?


Yes it's Object oriented, it was supposed to replace JS long time ago, but google kinda dropped the ball on that. I wish it replaced JS. Dart was almost dead for a long time but flutter kinda saved it. Developing on flutter for cross platform applications has been a joy to work with even though there are still a lot of drawbacks to flutter right now.

you can find their blog here where they talk about future releases and planned features https://medium.com/dartlang


Dart is an object oriented language with optional type inference. It's not replacing JS but it's better designed.


That's subjective and I'm sure it is for you. I personally prefer TypeScript.

I'm glad to see passionate developers keeping on both sides. That's how we grow and become better.


that's like saying VHS vs betamax is subjective. VHS won but wasn't better. Or Minidiscs vs CD's. It's mostly due to marketing fails and people hopping onto marketing bandwagons and pre-estalbished products.

TS is more popular due to combination of google dropping the ball in defining the standards and getting others onboard with them cause they overestimated the leverage they have, failure at marketing it and how everyone is already bought into Javascript.


No, it is not "better".


yes it is


My use case is a bit odd, but I've been using it for small personal web projects — so small that no dependencies are being pulled in and bare tsc is being used in place of a bundler — and as someone who doesn't have all of the ins/outs and do's/don'ts of JavaScript committed to memory (the vast majority of code I write is Swift or Kotlin) it's wonderful to have something catching errors before I save and reload the browser window as well as preventing "silent" bugs JS is notorious for.


Same here, I've found it very useful in projects where I don't have a lot of dependencies.

In another project with more exotic dependencies, it has become a hassle somewhat. I've found learning the .d.ts syntax to help easily get out of a situation, but it was a learning curve I still run into sometimes.


I find that I just make the .d.ts files any types

I could document types for that module, but I don't, and instead assume types as the output of code I have that interacts with them


I do that sometimes too. Sometimes I type the couple things I need out of a module. If it's something I end up relying on more, I usually start digging deeper and end up cloning it. The hardest are the large libraries with no types and no DefinitelyTyped types. Also monorepos can be annoying, when the main package is typed but the individual packages aren't, if you have to start poking at things deeper.

You do get a lot of escape hatches for different outcomes though, dependant on amount of desired effort


I add more thorough types for dependencies than for my own code, specifically so I don’t oops myself on other people’s code I’m less familiar with.


Although this seems to be the opposite sentiment to what many are saying which is that it's more useful in larger projects, with many contributors, I think I probably understand this side more.

Dependencies are where it starts to get tricky. It also gets tough when someone else has configured TypeScript, or you need to add some complex config. I would still opt out for smaller projects because they don't quite benefit so much from TypeScript, and eventually I would expect to run into something that would eat at hours of my time for a simple change.


Offtopic perhaps, but if most of your code is in Swift or Kotlin, have you tried the new Kotlin frontend support? I don't have any project where I can use Kotlin in the backend right now but I've always wanted to give the Kotlin frontend a go as an alternative to TypeScript.


I haven't, mostly because none of my front end web projects feel large/complex enough to justify the extra overhead (probably wouldn't even be using TypeScript if it were any more involved than running `tsc --watch` in a terminal window). Might look into it for future projects though.


Are tests useful? Because this is what TypeScript gives you: it helps you avoid regressions.

If I change a signature, tests fail. If I pass junk data, tests fail. It's like invisible live tests and people forget this.

As in the other recent discussion, yeah, you can live without tests and you can live in JS-land. Whether it's worth it it depends on you. TS and traditional testing lets me ship updates without even opening node or the browser.


Tests are great and the usual argument from static typing opponents is that they almost completely replace the regression safety from static typing.

Types are not the same as tests at all, tests are much better at giving you a glimpse of what the code even does.

For clarity, I'll define a static typing opponent as somebody who believes that the return on investment for static typing is negative.


> tests are much better at giving you a glimpse of what the code even does

Types do that, they tell you the expected input and expected output. No type nor test is all-encompassing of course, but it gives at least some information.

No test will guarantee that a function will never return a number. Types, if valid and without prototypal shenanigans, can.


While I agree that static typing provides some of the benefits of unit tests, I think it provides much more than that: compiler-assisted renames, code completion, extra code documentation...


Short answer:

It is worth it if you want me on the team. I refuse to work with anyone who throws out TS for JS in 2023.

Slightly longer answer:

I have said a number of times

    "Javascript is a simple version of Java in the same way as a bike with one wheel is a simpler version of an ordinary bike."
The same can be said about JS and TS. If you want to do any serious work you go for the serious thing even if it means occasional adjustment of brakes and gears, or in Typescripts case, sometimes figuring out something.

If anybody suggest to use Javascript today I won't take them seriously.

i) I have used Typeescript since 2017. For some reason I don't have these problems and never had.

ii) Yes, some libraries are poorly documented, that is for me a reason to prove why I am a software engineer by either figuring it out, complain until they fix it or even better use my gut feeling and use some libraries that aren't stuck 10 years ago.

iii) Error messages can be hard, but compared to debugging the mess that happens without typing it isn't hard at all.

iv) Have someone look at your project setup.

And before someone says I don't know Javascript: I wrote my first javascript application (OK ECMAScript since it was in Adobes SVG plugin), which was a working map, dynamically updated based on GPS position, back in the spring of 2005, that is half a year or so before Google Maps and years before most people took Javascript seriously so I should be qualified to have opinings. Yes, it wasn't production quality, but I built the logic more or less alone in 5 months in between other school work.


I don’t want to sound harsh, but saying Javascript is a simpler version of Java just tells me you have never used Java seriously.

It’s like saying Korean is a simpler version of Spanish.

Yes, Java and Javascript are both programming languages, but they don’t even share the same paradigm.

You might be confusing the motivation that led to the creation of Javascript with the actual implementation.

Having said that, I have used Java professionally for more than 7 years, then I switched to mainly Javascript, and later to Typescript, and I’m never going back. I agree with your overall point.


You misunderstood it : )

I love Java and despise Javascript.

In my opinion it is up there with null and other billion dollar mistakes.

The language only works as well as it does because hundreds of people smarter than me have spent hundreds of man-years creating toolings and ecosystems around it to work around all its problems.

This is not to be read as a dismissal of Brendan Eich or anyone - it is totally amazing that he threw together a language that has worked so amazingly well in three weeks.

But everytime one switches between TS and JS one wonders how much money could have been saved if he had somehow invented TS instead back then.


How about instead of analogies (which we've misunderstood even on this thread), just say this: "Java and Javascript are very different languages, don't be confused by the similarity of the names".

Of course, at this point virtually everyone knows this, now we are only arguing about which analogy to use to describe something we all understand.


He said "in the same way as a bike with one wheel is a simpler version of an ordinary bike." Meaning, not the same thing.


I don't think that's what he meant.


ha, If I was on that team I'd seriously consider opting for vanilla JS just for not having to work with you.

People who make such absolute claims are in my experience causing more trouble than they're worth. They will always nit-pick on anything anyone is saying causing a toxic atmosphere. Frequently a little later I then figured out that such people think like that because they haven't seen enough of the world and the gigantic amount of options you have to solve your technical problems.


Totally fine with me.

If you don't need my advice you can save a lot of money by not hiring me. Edit: The reason why people hire me as a consultant is hopefully because I give clear and valuable advice, and on JS/TS, if TS doesn't work better you are very probably doing something wrong.

But don't complain to me when JS bites you behind again and again.


q.e.d.


With a attitude like that, I wonder if it is worth having you on the team. Might just push me to pick JS then.


Comparing Java & Javascript? This reminds me the last recruiter message I got on LinkedIn. "You are a Javascript expert, I have this mission for you with the same language! They're looking for a Java expert!"


I am pointing out that they are not comparable except very superficially.


It's a pointless point to make, and I think people are rightfully calling you out for it. "If my grandmother had wheels she'd be a bicycle."


whoever said that javascript was a simple version of java? the two languages have almost nothing in common - at least a unicycle and a bicycle share the concepts of "wheel" and "pedals".


The syntax is very similar on the surface, at least compared to Perl, PHP, Python, C and - I would personally say - C++ and a number of other languages.

Yes, there is no way you'd mistake one for another if you have worked in any of them - but they look superficially similar.


No they really do not


Java has wheels and pedals. Javascript only has objects that say they are wheels, and objects that say they are pedals, but which are really both and neither at the same time.


Smalltalk has wheels and pedals. Java has AbstractBicyclePartFactoryBuilderSingletons.


Schrödingers Java


In my experience yes, to the extent that I don't intend to write vanilla JS ever again if I can possibly help it. If you've done webdev professionally in the past 5+ years you've almost certainly already been transpiling so to draw the line at introducing something as massively useful as static typing seems both arbitrary and bizarre.

FWIW I can't recall the last time I reached for a 3rd-party library and found that it was lacking types. The DefinitelyTyped project has really done a remarkable job expanding type coverage. And even in that rare case where you might need to add type definitions yourself it's simple enough to do so.

There's a ton of room for improvement around error messages, no argument there. The TS team is very much aware of this and they're working on it but it'll take time.


I feel like TypeScript is definitely worth it BUT it seems to be getting ever more powerful but not in a good way, in complex way.

Too much time is spend fighting TypeScript as opposed to writing application code.

I have a question for the language experts out there .... why is TypeScript getting so complex? Are other strongly typed languages this complex? Or does the complexity arise from trying to overlay typing on JavaScript which is an incredibly dynamic language?

And if it is the case that TypeScript's complexity keeps going up because essentially "strongly typed JavaScript" is a hack, then should we all be moving to a much simpler strongly typed language that compiles to WASM, and yet still richly interfaces with the DOM and browser APIs?

Does TypeScript just have to keep getting ever and ever more complex and detailed - is that the unavoidable future?


I don’t know but my experience with TypeScript is it is the C++ of type systems- it wants to have all possible features and caters to the demands of the most sophisticated users at the expense of the 99%. I also enjoy using simple TS like I like to write simple C++.


I wonder if maybe the TypeScript team should have stopped at some point and said "no more, we're just making complex now!".

The Wizards Of TypeScript seem to be implementing ever more obscure use cases with ever more diminishing returns in terms of the number of programmers who will ever use those advanced features.

What happens when you have a fully funded development team at Microsoft, who actually finished the job long ago? They just keep developing, ad infinitum.


> Or does the complexity arise from trying to overlay typing on JavaScript which is an incredibly dynamic language?

Mostly this. There’s still some valid constructs in Javascript that are inexpressible in Typescript (though I’m inclined to believe most common ones are covered by now).

But to be honest, that’s not anything you are forced to use. A lot of people do because the benefits it brings are so nice.


I have such huge issues TypeScript decorators. It's so obvious on how that would work in JavaScript, but it looks completely foreign in TypeScript.


You answered this all yourself. Yes, it's a hack. Yes, probably some other WASM-targeted language will exceed Javascript's mindshare. But that may take many years, and you need to build software now.


Typescript doesn’t just statically type. That’s easy. It does program flow analysis to 1) infer type and 2) ensure the inferred types actually work. I think in most statically type environments, the type analysis engine relies a lot of on the developer to define the correct types in the correct places, but the types in TS are always _logically_ correct. As in absolutely correct (unless of course you eject from the type system using coercion).


> but the types in TS are always _logically_ correct. As in absolutely correct

Erm...

    type Test = Array<number>;

    const xs: Test = [];
    const x = xs[0];
What's the type of x, according to typescript's default behavior? It's number [0]. What's the logically correct type? Some sort of a Maybe<number>, which typescript doesn't have; so a number|undefined instead. Most people don't use typescript at that level of soundness, both because it would be painful, and because typescript doesn't have it as a default.

[0] - https://www.typescriptlang.org/play?#code/C4TwDgpgBAKhDOwoF4...


there is --no-unchecked-indexed-access option for it. Which is not on by default or in --stric mode because indeed in practise it's painfull

https://devblogs.microsoft.com/typescript/announcing-typescr...


I’ve never found it to be overly painful. If you’re accessing values this way (on an index vs defined fields), you’re already treading into iffy territory, structure-wise, and its good to undermine your assumptions about what’s at the index. An extra check might seem very hand-holdy, but I’ve been doing JS long enough now to have seen a large number of errors originate in this class of index access.


I'd say for most people, beyond small scripts/cli/micro-microservices, the ceremony of setup/environment overhead for it is worth it, and continually pays dividends. You can usually copy-paste a common config file around to bootstrap.

Most of your (pretty good actually) critique are points to make the least-bad way of doing JavaScript even better, and I'd agree could be improved.

Others have taken notice.

"Native support" of TypeScript is done by Deno. And tight TypeScript (and other adjacent tooling) integrations with VS Code and WebStorm.

And transpilation is being worked on by various builders. Stripping types and running through esbuild or swc is fast. For typechecking part, was a proposal to have TypeScript be rewritten in Rust for performance.

We can lament that JavaScript went from being a web document enhancer to being shoehorned into a full application compilation toolchain, but the old Jquery thru Expressjs era of doing things has significant drawbacks for full sized applications/APIs/etc.


I haven't found much agreement, or at least to the extent I believe it, that Javascript and HTML and CSS have all been shoehorned and built upon completely beyond their original specs.


Those sound like the least controversial opinions ever.

What's nice is that despite looking ugly, those shoe horns have done a pretty good job, and they all make effective tools for building useful stuff, and that stuff can be built by people who aren't very good at building stuff.

It's very much a success story that so much html/css/JavaScript is a garbage fire. They're really effective tools, up there with excel


I like it. I wasn't convinced it was worth it for the first year or two, especially when TS was young, but the devs have done a great job and have paved over a lot of the weak spots. Things I didn't even expect would get fixed have been fixed.

I just try to type things 90% of the way, until it's good enough, and slap an `as` in there if I get too annoyed or it takes too long to fix. Don't even care. It doesn't put me in a worse spot than JS would have.

Getting completions on all my giant objects is wonderful.


> I just try to type things 90% of the way, until it's good enough, and slap an `as` in there if I get too annoyed or it takes too long to fix. Don't even care.

Still a js dev in spirit <3


I am quite surprised at the turn out in the comments here against adding type checking to JavaScript.

In my opinion, TypeScript is not only essential in the context of any professional project, but it features one of the most ergonomic type systems I have ever worked with.

There are certainly pain points with certain TypeScript features (e.g. enums) but any project that takes me longer than 5 minutes to write, I need type checking. If I can't be bothered with setting up tsc - and setup difficulty is a valid criticism - I just use jsdoc.

I have seen TypeScript take the heat when applied to JavaScript projects that implement multiple trendy programming paradigms. Often times the projects themselves are so complex that adding a type system requires type-kungfu. It's not the type system at fault - but a needlessly complex architecture.

Love TypeScript. Wish there was anything like it that compiled down to static binaries.


> it features one of the most ergonomic type systems I have ever worked with.

This is surprising. Which other type systems have you worked with?


Yes, I found the ReScript/OCaml type system much more ergonomic.


Having worked with OCaml and F#, I find that TypeScript requires fewer changes to non-type code in response to changes to the types.

For instance, given `type T = { a: string; b: string; c: string }`, if I want to make `b` and `c` nullable but always provided together:

    // OCaml
    type TOpt = { a: string; bc: (string * string) option } 

    // TypeScript 
    type TOpt = T | { a: string; b: undefined; c: undefined }
With the TypeScript approach, code which worked with T still works with TOpt (only requiring an `if(x.b)` guard). With the OCaml approach, any code that accessed b or c needs to be rewritten.

The same applies to cases where an object can be in several different modes, but some properties are present in all modes. For example, an AST node can be a literal, identifier, binary operation, etc. but it always has a source location and an inferred type. In OCaml this has to be represented by either separating a "common properties" type from a "kind of node" union type:

    type node = { loc: location ; inferred_type: exprtype option ; kind: nodekind }
    and nodekind = Lit of string | Id of string | Unary of op * node
Or by repeating the common properties in all union type constructors:

    type node = Lit of location * exprtype option * string
              | Id of location * exprtype option * string
              | Unary of location * exprtype option * op * node
Both are tedious (although F# makes the second one slightly less tedious by allowing one to define computed properties on union types). By contrast, TypeScript allows you to have only one type:

    type NodeCommon = { loc: location; inferred_type: exprtype|undefined }
    type Lit = NodeCommon & { kind: "lit"; value: string }
    type Id = NodeCommon & { kind: "id"; value: string }
    type Unary = NodeCommon & { kind: "unary"; op: op; node: Node }
    type Node = Lit | Id | Unary


> Is Typescript worth it? > I want to skip over the static typing benefits argument…

Typescript, as the name implies, adds types to your script. If you don’t see the benefits of types then typescript may not be for you.

> My issue is with the amount of extra work it places on developers… and doesn't deliver all that much value.

If you think adding types doesn't add much value then typescript may not be for you. In my experience, types are defined once then provide a lifetime of value.

> you are at the whim of TypeScript developers and how they decide to progress with the language.

This is true of any library, programming language, operating system, hardware, etc. But adding types isn’t somewhere I’d worry about backward compatibility being broken. All the newer versions of typescript are backward compatible. If you have a library that requires a newer version of ts then upgrading ts won’t break anything dependent on earlier versions.


> If you think adding types doesn't add much value then typescript may not be for you. In my experience, types are defined once then provide a lifetime of value

You have misunderstood the OP. The full paragraph is:

>> I want to skip over the static typing benefits argument, because I think it is well understood that static typing is a good thing and if we could bless JavaScript with a built-in and robust typing system then I don't think many people would be against that. My issue is with the amount of extra work it places on developers, much of it the "dumb" kind of work which can eat up hours and doesn't deliver all that much value.

Summarized: "I agree that static typing is a good thing. My issue is with the extra work (required to use TypeScript)...which doesn't deliver much value".

That is - they are saying that types deliver value, but that the extra busywork required to use and maintain a TypeScript project (e.g. keeping dependencies up-to-date) does not - and, by implication, that the overhead of this maintenance work is enough to make them question whether the (acknowledged) value of types is worth it.

(Note that I do not have a horse in the race as to whether the OP is correct in thinking that the overhead of TypeScript _as a language_ is greater than the value of the types. I haven't used it enough to have an educated opinion. But I am certain that you are responding to a point that was not actually the one being made)


But that is either not a properly formulated argument, or it denies the benefits of strict(ish) typing. You reformulate it so that one weighs out the other. That would only be the case for projects where you do more work integrating libraries than actual programming. That's something much easier to discuss (IMO), but is it what OP asked?


>You reformulate it so that one weighs out the other. That would only be the case for projects where you do more work integrating libraries than actual programming.

No, the net gain with typing with static types as compared to without it, would be less than the increase of time spent with integrated libraries, rendering a total net loss.


That's fair. It appears his issue is more related to libraries with broken, undocumented types and typescript's opaque errors when an error occurs in said library. Unfortunately I think he's conflating typescript's role and a library with broken type definitions (I have no idea whether the type definitions he's had problems with are provided by the library or a community effort that may not keep pace with the official library). When the type definitions don't match the official library it can definitely cause a tremendous amount of frustration and make one doubt the usefulness of types.


> Unfortunately I think he's conflating typescript's role and a library with broken type definitions (I have no idea whether the type definitions he's had problems with are provided by the library or a community effort that may not keep pace with the official library). When the type definitions don't match the official library it can definitely cause a tremendous amount of frustration and make one doubt the usefulness of types.

I am not trying to cast blame on any part of the TypeScript system. I have tremendous respect for the TS team and the problems they have had to solve to get this far. My point is, is it actually worth it? Whether people document their libraries is part of the equation, even if it may not be a direct responsibility of the TS team.

I thought things might get better as the community matures, but I am still dealing with issues that seem to sometimes outweigh what I get from it.

And I want to be clear as well that I mean to shed light on this thought and hear people's opinions. I am still open minded, and will continue to decide whether to use JS or TS depending on many variables whenever that decision comes my way. For personal projects I am currently in the boat that I would not choose TypeScript.


> If you don’t see the benefits of types then typescript may not be for you.

At this point in my 20+ year career working with mostly dynamic languages, my feeling is that if you don't see the benefits of types, then programming isn't for you.


I would narrow this slightly to "programming with other people". For instance, I love Python for small personal projects and interview questions and stuff like that, but I've found working with it professionally to be much more of a headache.


>my feeling is that if you don't see the benefits of types, then programming isn't for you.

Maybe it isn't "types" that is the problem, but the way types are implemented in TS. I never had these problems in Java as I do in TS.


Eeexactly.

Untyped Python and Javascript are amazing if you're doing things solo or maybe with one other person who has the same style.

Now try that with a 20 person group poking the same codebase. The amount of weird bugs you run into because it's not clear what type(s) a function can take in or return is bonkers.


Types are indispensable even just for me. They reduce how much I have to jump over to the docs and how much runtime debugging I do.

Most importantly, they help when I revisit something after even a few weeks and forget what certain parts of the code did.


> static typing is a good thing [...] My issue is with the amount of extra work it places on developers

This is one of the eternal complains about type safety, somehow mitigated by type inference. I believe it is totally worth it in the case of Typescript.

> i) Like a framework, you are at the whim of TS devs as it gets updated (edited)

As a language, it has proven quite stable. Even if development stopped tomorrow you could keep the current version forever.

> ii) Libraries are badly documented

It is inconvenient but, since they are js libraries, they are compatible. You do not need specific ts examples, although it is extra nice.

> iii) Error messages are hard to follow

Did not run into this issue myself but fair enough.

> iv) It requires yet more transpilation

tsc compiles ts into js. Depending on what you use, you could get rid of webpack etc. and just use tsc.

In summary, for me Typescript is totally worth it. All this lost time you mention is different from the lost time adapting to x framework or y packer update, since it reduces errors down the line. It might feel like it is slowing you down, but you can always use any for certain modules and type things at the interface. It is still your decision what to type, the language gives you the tools to do so.


The question of whether it's "worth it" really boils down to you and your specific requirements.

Even within the same project, there are times when I don't want typechecking - when I am prototyping something out and want to move fast.

And there are other times, when I want typechecking - when I am finalizing a feature implementation or doing integration with existing logic etc.

It's not a framework. It definitely is a language in its own right.

But from personal experience, the group productivity goes way up with larger codebases with many ICs working on it. Unit tests become type checks. It opens up a lot of extra bandwidth for more sophisticated functionality or better tests.

Solo IC, working on a small project, with no intention of ever writing tests - you might see TS be an overhead.

To sum up, your requirements decide whether it's worth it.


I have seen this IC vs team aspect discussion before, and it definitely has merit. However I am starting to question if it's even worth it for larger codebases used by many devs, which is why I wanted to pose this question.

Can you think of cases where it's actually prevented a bug where that piece of code is unit tested? I have been actively monitoring for this to happen, but so far not seen it (I think I have seen it catch a couple of bugs for code that did not have unit tests).


Types let you limit the size of the input space - JS lets you go ahead with (foo, bar) where they could be literally anything and you have to handle every edge case to test that (and I bet if you fuzz you'd find stuff) your unit tests don't handle. With a typed language I can specify the input space and know with certainty anything that calls that function (and compiles) is going to be within that space. This lets you dramatically reduce the complexity of your app, tests, and stress of refactoring!

Fwiw I'm an SDET and I regularly find bugs, on a daily basis, in a startup of around 40 people with a Python/JS web stack that TypeScript would have caught (and am pushing towards moving over to it).


Unit tests only trace one path at a time; static types cover huge possibility-spaces at once. But of course there are things they can't reason about, which is why we still test, but each of the two is better for catching different kinds of things. One isn't sufficient to replace the other.


A unit test can succeed while being completely wrong.

Eg. You test code that calls a dependency that returns a bool, but your tests assume an object response

Unit tests imply assumptions about the integrations, whereas types specify those asumptions


Solo ic on a small project, you don't write tests? That's the easiest time to write tests! You don't have all the complicated context set up or writing test data, and saves you the run/debug loop for setting up specific situations.

My childhood not knowing about tests had a ton of wasted time trying to check that a change worked


100% worth it to me. I love typescript. Working on large enterprise applications where one function calls other function and it goes 10+ layers deep I don't know how I would work without typescript. Just being able to see this function takes argument of type FOO and returns type BAR[] is incredibly valuable.


One thing I often tell people is that if a particular technology makes it easier to work with code that's 10 layers deep, it will also make it more likely that people will write code 10 layers deep where they would previously do 5 layers.

Somewhat similar to https://en.wikipedia.org/wiki/Jevons_paradox


Yes! This is one reason I really like Go. I'm not exuberant about it the way some folks are, but amidst ambivalence about some aspects of it, this is one thing it really gets right. While it's hardly impossible, it's not that easy to write completely impenetrable code Go.


Not in my experience. People will happily write 10 layers deep if you let them anyway. Technologies like Typescript make it easier for other people to untangle the mess.

As an example, what parameters does `manim.animation.creation.Create()` accept?


Some people make things as deep as they can handle. If you reduce the pain from deep hierarchies, you will inevitably end up with deeper hierarchies.

Also, doesn't your example prove my point?

I'm saying focus on types leads to deeper hierarchies. Your example has types and a deep hierarchy.


> Your example has types and a deep hierarchy.

It was originally written without type hints. It looks like somebody has added them since I last used Manim (a couple of years ago) to make sense of the mess!

In my extensive experience code with static types is always easier to follow than dynamically typed code. There's no contest.


That's a lot of layers for a codebase... I see that it could be useful in that situation, but since you presumably need to test and QA your code anyway you could also throw in a console log statement.

There is also JSDoc.

Although these solutions might not be quite as nice, I'd wager they'd save quite a bit of headache and time.


I have been using TypeScript at work since 2019. Personally I am not convinced that it is worth it, broadly for the reasons you note and also because TypeScript has in practice a soft dependency on Visual Studio, and in turn other MS services such as GitHub and Axure. Adopting TypeScript can often lead to de facto vendor lock-in.

There is a good argument for using types (and also a good argument for not doing so). If the argument for wins out, then types will be included in the native js spec and the need for TypeScript will disappear. If the argument against wins, then TypeScript will also disappear.

If TypeScript really floats your boat then by all means use it, but treat it for what it is- a hairy dependency that only a minority of developers love or need.


> TypeScript has in practice a soft dependency on Visual Studio

How do you figure? I've been fulltime typescript for almost 4 years now and never opened VS or Viscose once in my life.


I don't like JavaScript, I don't like TypeScript, I don't like front end development at all. Is typescript worth it in my personal projects where I know all the code and they are pretty small? In my opinion, no. Is typescript worth it at work, where multiple people interact in a large codebase? Absolutely. Asking if a language is worth it is pointless unless you add "to my use case"


Can't believe how long I had to scroll to find the answer I agree with, effectively: "it depends".

Going with car analogies, the question is similar to "Is a bus better than a race car?" - there's no correct answer without more context. How many people use one or the other, how many people praise one or the other, that's no help either.

That said, regardless of whether it makes me happy or whether it's a solid technical decision, TypeScript appears to be used somewhat widely at this point. So learning to deal with the complexities and gotchas of it is IMHO worth it for anyone who's serious about web development. No need to become a zealot though, there's no need to find and defend some silver bullet. It just depends.


The reason may be that people not using either in a professional environment tend to comment faster on HN.

I agree that you must learn it at least a bit for web development. I occasionally have to fix some bug and so I learned it. Another month of income earned.


I've worked on multiple Typescript projects for years and I'm still not convinced it is actually an improvement over working with plain JS.

Lately I've been using Typescript's JSDoc comments just so I don't have to deal with transpiling code but still get most of the advantages like editor autocomplete and warnings.


As humans it is easy to forget the time savings that we don't see. For a project that uses a lot of Type annotations, it is like getting a bunch of unit tests for free or writing a bunch of boilerplate code to validate inputs.


Yeah it feels like the Seinfeld Effect here. TS is so pervasive now that its vast upsides are just "the new normal", taken for granted.


I worked for many years without TypeScript, and the development flow was a lot more pleasurable without a big difference in the number of bugs I saw us shipping.


I work on a ruby code base that has extremely good test coverage, something around 20,000 unit tests for a relatively simple app, and it’s still almost impossible to update ruby or rails without breaking something. The thing that broke is always impossible to predict from reading the release notes.

The most infuriating thing is it’s almost always something a typed language would have picked up like a functions parameters changed or things removed.

No amount of unit testing or browser automation is a sufficient replacement to type checking.


I don't have a lot to add except that my experience with it has been very positive; your complaints are mostly valid, but for me those pain points disappear in the shadow of all the things I no longer have to spend time stressing about or debugging


So much this.

If you’re learning JavaScript or any components of the language, you’re better off just starting with typescript (given the technical acumen up front).

It’s absolutely a no brainer, long term roi. If presented the opportunity to integrate or use now vs later.

The community is also very active, and it’s under Microsoft - and has been well maintained and quite active. Lots of libraries.


> you’re better off just starting with typescript

It depends. The tooling is still a barrier (even though it's gotten smaller); the cost is small for a real project, but for someone who's learning and knows nothing about the ecosystem, it could be a real obstacle to dive all the way in at once. The exception would be if you're starting with something like Deno that integrates TypeScript seamlessly. Outside of that, tools like esbuild have significantly lowered the bar vs a few years ago when you had no choice but to configure webpack + babel. But even esbuild isn't quite zero-configuration


If you're just starting off with JS or TS you shouldn't be messing with tooling at all. Just install one of the many create-react-app derivatives, run one command and start developing. All those boilerplate generators support TypeScript now, too, so you don't even need to do anything extra to start using TypeScript. Even TypeScript itself can be incrementally adopted since it's a superset of JS.

You will outgrow those app generators, but for a learning project? There is no need for you to even see a webpack file.


I use TS as standard now (because every job requires it), but I dislike it immensely.

I've used static langs like Java and GoLang and prefer them over TS. Heck I even like ruby-rails more. Since I'm fullstack (TS on FE/BE), it's hard to move 100% away from TS (becz a use React) and it irks me how everything has changed the last 10 years of so.

I am a seasoned developer and can code (in JS) extremely fast, clean and performant. With sufficient test coverage you can go a long way. Of course if you use TS and change something important, the compiler will tell you all the places you have to refactor. This is super useful.

However in my experience with a fair amount of TS codebases, there has been a tendency for devs to use as many clever TS features of possible (e.g. utility classes and generating crazy generic types from multiple types). I detest this style of programming, becz when you have to can't get something to work, it's a pain to try and understand the errors. This also extends to TS enabled libraries which can be challenging when you try and do something non-standard.

I burn time trying to understand the errors and getting TS out of my way, so I can get on with the task at hand. I find cases that if you look at the logic I've written, there's not a chance that something can be undefined and yet I have to wrap code in "if's" just to satisfy the compiler.

Even though I have a ton of experience, I deliberately code for that junior devs can understand/debug/work-with or the support engineer who just got woke up and trying to fix prod, which in my experience, isn't a common approach anymore. This is part of the problem IMHO.

Most devs I talk to are using TS as their first language and have mostly never experienced the joy (and lack of safety, I grant you) of dynamic/non-typed languages (e.g. ruby/lisp). Get a lisp-er to do TS and start hearing the flood of swear words. lol.

Of course, I understand the benefits of TS, but for me at least there's no joy in it and that's one of the reasons I got in this game in the first place.


I've seen the codebases created and maintained by people who "don't need types because it just slows me down."

Hard pass.


Many of the most pleasant codebases I have worked with were built before TypeScript existed. Building a good codebase takes a lot of care and thought and can't come just from using TypeScript, in fact the worst cases I can remember happen to be TypeScript.

By no means am I saying TypeScript is the reason these codebases were poor, however it also didn't seem to help them all that much.


This is going to sounds super hash and will probably ruin a lot of folks days, so I'm sorry, but...I love how these snooty elitist overgeneralized denunciations of "those typeless savages" pass for reasoned argument and justification within the hoards of the type zealots.

When I think in reality, it's just people who were forced to use TypeScript because their workplaces gave them "no choice" (always a choice folks), are expressing their pent up rage, through a sort of weird, Stockholm-syndrome projection response--"Those non-hostages have it way worse than us, they're actually beneath us: subhuman even. I'm thankful to our Typed overlords for giving us dignity, refinement, and superior codebases. All praise the ascetic self-flagellatory TS gods."


This is absolutely on point and just had me cry laughing. Thank you.


As for "worth it" — as someone replied in another comment, it's a question for you. You better than us know your use case, your strengths and weaknesses.

Me, I love typescript. It's an extra reassurance that my code will probably work correctly — and even though it isn't as trustworthy as Elm, Haskell, or Purescript, it's better than nothing. It is a good pair programmer who has many times saved me from stupid mistakes I made while writing code. And it holds my hand while I am refactoring — I would be scared to do that in a javascript codebase. Tests would help with refactoring, of course; but they aren't as exhaustive as a static type checker is.


My question wasn't so much asking whether I should continue to use it, that depends largely on what people have already decided to use on a codebase, or what a team or company has decided to do.

I pose this question more so to understand how others are thinking about TypeScript, and whether there is sentiment out there like mine that the tradeoffs are not really worth it in any case, regardless of what is being built.


We have been using typescript in large scale JS project with 15-20 library modules and 7-8 product modules. I cannot think of building such product without typescript. When we compile all libraries and products and see no TS errors, we know at least that we are referring to correct properties, and wiring the shape correctly.

Typescript has bunch of "clever" things but you don't have to use it. We probably use 30-40% of TS features and that is more than sufficient for us. With that said, here is what I think about your questions.

1. Agree, and it is not any better without TS either. In case, a library is not compiling with your TS version, we ignore the error, put a FIXME there and remove the "ignore" sometime later

2. Yes but that is not TS problem. Without TS it is even worse.

3. Agree sometimes, we get so complicated errors. We search around and see if any smart people have figured what that means. If not, ignore and move on with a FIXME

4. Since many years, we are not writing any JS which doesn't need transpiling. If not TS, you would be using babbel or some other tool most of the time anyways so we haven't this to be an issue.


We probably use 30-40% of TS features and that is more than sufficient for us

Exactly. Some people seem to have the idea that you have to spend weeks writing esoteric type definitions before TS will work for you, which is just not true. You can get a large portion of the benefits with very little additional work, often just adding types for function arguments. (In many cases those types can replace comments that were trying to convey that same information, with the advantage that they won't get out of sync with the code). And for code that intentionally takes advantage of dynamic typing, it's perfectly fine to slap "any" on it rather than trying to come up with a bunch of clever types.


#1 – You don't have to upgrade TypeScript versions till you are ready, and newer versions never have breaking changes anyways. The syntax remains strictly compatible with ES6 and beyond. Packages you consume publish compiled JS and aren't dependent on specific TypeScript versions at all.

#2 – If libraries haven't published types, just use them as pure JavaScript (which is what you would have done anyways). Lack of documentation again applies to both JS and TS equally.

#3 – I assume you are talking about compiler errors? I have personally found them to be simple to understand, especially when the exact location is highlighted in your IDE. At runtime there will be no difference since it is all the same JS code under the hood.

#4 – Yes transpilation takes non-zero time. TypeScript has a lot of tooling around incremental compile/watching for changes, so I don't think it should really be that much of a burden during development. I have worked on massive TS projects and don't even notice the compile task running in the background.

I find this post weird because TypeScript does have some real drawbacks – overly complex type system, makes the codebase more verbose, false sense of security (no runtime type mismatch errors), mix of typed and untyped code in codebase etc., but your reasons for disliking it all seem superficial and easy to overcome.

In my personal opinion everyone should be starting new JS projects in strict-mode TypeScript by default unless there is a reason not to.


Regarding #1: this is not true always. Libraries publish types and their type definitions could use new TypeScript features that could force an update.



I didn't know about this, thanks.


This is rare (I have never run into it in many years of writing TS code and pulling repos from NPM), and if it does happen you can always ignore the definition and turn it back into a plain JS package.


Not rare. Happens every 12 months or so in my experience as a library maintainer. It really sucks that Typescript, let alone .d.ts files produced by the compiler, don’t follow anything resembling semver.


> newer versions never have breaking changes anyways.

I've also seen changes to the type system that break existing library typings. (e.g. when they started strongly typing generators.)

I suppose this only happens when you're using the more strict compilation settings, but that's a major draw of typescript in the first place.


That's the exact case I was referring to in i) - and what drove me to write this post :)


> and newer versions never have breaking changes anyways

Huh? Typescript release note regularly contain information about breaking changes. They may not be dramatic; but they are there.


#3 really depends on how complex your types are. Lots of legacy JS libraries and applications can be quite... esoteric when typed. Then there are the people that love playing with the type system for the sheer joy of it.

The net result is that greenfield TS projects often end up simpler and faster but that’s not very useful for someone buried in an old JS project that enthusiastically abuses the dynamicness allowed.


+1 for the strict mode. I consider it a must-have quality requirement.

I honestly don't understand why it's even optional, as being able to know what is nullable or potentially undefined is extremely important, and not having it can lead to tons of bugs.


Just to add to #4, I've worked on some large codebases where transpilation starts taking a very long time, and I begin to think "wow, this is really straining TSC"... so far, every time it's happened, it's been because some sort of data files weren't being excluded from the build.


Idk if I’m just an idiot but my company’s codebase for the last year has had pretty slow tsc compile times and nobody on my team has been able to make it better. Probably since we have a decent amount of generated code that pushes the amount of source code up considerably, but still no good answers to make that better.


I don't do anything with generated code. But is it necessary to generate that code every time TSC does a build? Could it be independent? I usually use two different ts export indexes, and create two dist JS files for each app. Most of the boilerplate that rarely gets touched (user management, login and signup screens, common UI elements, utility code) is essentially in an outer JS file that loads the inner JS with the business logic and meat of the app, but has no imports from the inner JS whatsoever. They're basically two separate projects. Not that I've noticed much difference with tsc, but it makes webpack or r.js faster if you can create separate webs of dependencies and only need to repack one of them without touching the other...


If you are autogenerating code you can generate it in JS and skip compilation altogether.


The point of the generation is to build type safe API clients, not for the runtime behavior, so that doesn’t really fly unfortunately.


Of course, there's more than one way to build a good product.

Personally speaking, I'd say that adding another layer of abstraction onto your stack shouldn't be a dogmatic thing that you just reflexively do without considering the actual needs of a particular project. TypeScript offers some benefits for certain types of complex projects, but also some costs and problems that might not be worth dealing with for certain projects.

It's a little bit like GraphQL in a sense. That's a phenomenal idea...for a product like Facebook...but probably not actually needed for every single project.


Could you describe the costs and problems that might be considered not worth dealing with?


The short answer is no. Typescript is not worth it. The reason is because:

- WebAssembley (which other, controversially better or at least more adopted languages also target)

- Javascript's spec. is not time invariant (https://github.com/tc39/proposals#readme)

- Typescript isn't the best solution (There are better less adopted solutions providing types, like Elm, Rescript, or Purescript)

For Javascript, the real solution is hygienic macros and contracts, but because `eval()` can't get no love or safety on the browser side, everyone on the server-side has to suffer.

Ironically, introducing a fake compilation step where Javascript transpiles to Javascript (not like babel.js which targets older JS, but literally just the same lang spec) is the way to side step the `eval()` problem, lol! (expanding those `eval()` in a fake compile step)


What is a bit sad is that JS and TS both get in the way of the development of something more sensible to replace it. I had hoped that WASM would make application development for the browser a bit more sane. I had hoped that someone would create an application framework for a sane, strongly typed, mainstream, compiled language that has decent tooling. With compiler and dynamic loading as part of the runtime.

JS is a garbage language. You need only look at identity or all the stupid asymmetries in the language to realize it isn't a well designed language. TS tries to fix that, and good job for doing that, but you can't escape the fact that it is desperately trying to fix a pig with lipstick, botox and hold-in pantyhose.


I haven't tested it but I know Kotlin.js exist and you can use it with React. It wouldn't surprise me if it is good but at the moment TS is good enough and "everyone" knows it.


I had some pretty strong pressure applied to use Typescript for pianojacq.com but resisted it for a very simple reason: no tooling other than an editor reduces the barrier for contribution so much that it makes it possible for outsiders that just know Javascript (a large multiple of the ones that know TS) to contribute to the project.

It also means there is no 'development environment' as such, it's just a repo on gitlab that anybody can read, fork and contribute to from within gitlab if they want.

I have also tried to keep the number of dependencies to an absolute minimum, which also helped to make something that doesn't feel like a moving target.


To make an anology.

Js is a shovel. Simple. Does its thing. Digs dirt in our quest for gold.

TS is like adding a two stroke petrol engine so the shovel vibrates up and down. Loud, jerky, difficult to handle.

A sane person looking in would wonder why not just buy a jackhammer(java/c#)? Or use an excavator(Rust/C++)?

Why is it neccesary to attach an engine to a shovel?


I think you are asking the wrong question. The right question is whether it is worth opting out of the benefits of typescript. The answer to that is probably no for lots of people. Another valid question to ask is if typescript is all there is when it comes to those benefits. And the question to that is also no. It's a nice step up from Javascript. But why stop after that? There are so many other languages out there that offer so much more. And some of them even transpile to javascript.

Regarding your points:

I) this is indeed endemic in the javascript world. I would not blame typescript for this. I work with Java and Kotlin a lot. Things are more stable there. Five years is short for compatibility. In the js world, six months is long.

II) The typescript annotations are documentation too. They help your IDE figure out what is what and enable things like autocomplete. The original js code probably isn't a whole lot better. Also, lots of libraries are developed in typescript these days.

III) That's what happens in weakly typed and highly asynchronous environments. Pure javascript just moves that burden to runtime. Better to deal with it before you deploy your code.

IV) Most modern javascript is transpiled. It's a compilation target at this point. So you might as well make full use of the fact that there is a compilation step. The packaging and minification is actually just as bad.


To me the language is very secondary to me as it exists in an endless swamp of:

- chaotic and baroque layers of tooling that need to be figured out and made to keep working

- a software tradition where poorly thought out ideas are implemented with vigor resulting in design by accident

- ...which then results in frequent rewrites

- a universe of low quality libraries and frameworks resulting in frequent discovery of serious bugs

- every project having lots and lots of dependencies

And that's before we even consider the language or the congenital defects inherited from JavaScript.


Yep. I've had the foolish (mis?)fortune of scaling a couple of frontend projects from small to not-so-small starting in JavaScript and then converting to TypeScript. In each one, starting out with vanilla JavaScript was faster (no build!), but at some point our velocity would slow as changes required more testing infrastructure. After switching to TypeScript, we were faster than before.

Sure, dealing with TypeScript can be a hassle, but it is less hassle than dealing with broken software.


> Sure, dealing with TypeScript can be a hassle, but it is less hassle than dealing with broken software.

Can you think of examples where it's prevented broken software? I would prefer to spend more time writing good unit test coverage which in my experience would catch anything that TypeScript would have caught. I have seen it be more useful for autocomplete and self-documenting code, which I could get using JSDoc or something similar.


The biggest impact was in refactoring working code.

Being able to change something, and then have my IDE know those types elsewhere in the codebase and change them automatically, OR give me a detailed list of where things have broken, immediately, is significantly faster than tracing through failing unit tests to work out what needs to be fixed.

It's not that it couldn't be replaced entirely with unit tests - it certainly could. If that's your preference, comprehensive test coverage can be more effective than TypeScript alone. But as an online helper in the IDE pointing out where I've messed up even before running unit tests, it can make writing and iterating on correct code faster.


Piping data around an application where each step applies a transformation. It is very difficult without a type system to keep track of what the inputs and outputs are supposed to be at each step. Typescript makes this a breeze.


If your entire codebase uses static typing, you don't even need an entire class of unit tests for checking the validity of inputs/outputs to functions. You can spend that time testing business logic instead.


I know it's happened, but I find out about the error before I've run the tests, or I've used the types to guide me to the correct code rather than writing without and then testing to find out if it's correct.

The autocomplete and documentation are about preventing broken software. You just don't think about it like that because it skips the seeing it break part


100% my experience too. It's not that much more work to get TS setup for a projects and the dividends for doing so are vast in the long run.


I don’t see the need for TypeScript. A lot of people seem to see dynamic typing as this big bad thing that should just go away.

I haven’t used JS professionally so maybe I don’t know any better, but I think dynamic typing should be embraced. There are A LOT of applications where you really don’t need to worry about types. And from my experience working with app/cloud code bases in C#, I’ve seen a lot of ugly classes that I can’t touch simply because they were written 10 years ago and I don’t trust them. My guess is the web world is plagued with all sorts of old code you don’t want to touch, I don’t think TypeScript solves that with static OOP.

I think the prototype based OOP approach in JS is better because you don’t have to concern yourself with all these hierarchies. You can have multiple car object definitions with dynamic typing, it doesn’t matter because it’s all about what’s being used in the moment. In static typing we expect a single concrete definition to be extended, composited, and reused in an intricate way. That way never works because what is defined today as “just the bare minimum” mutates into something larger and now everything inherited “needs” it too. But they don’t always truly need it, they just have to satisfy some argument. And of course that “single” definition gets duplicated across the code bases anyway. Initially we think of these approaches as elegant, but it almost always rots in its own hierarchal casket.

Dynamic typing allows cleaner OOP and its approach is more honest. “I need a representation of this abstract type right now”, not that type and a whole bunch of other crap that it’s fundamentally forced into bringing along for the ride.


i) TS isn't a framework. And you don't have to use it everywhere in your system. You can decide how heavily to leverage it, developing a 'core' TS subset that powers a broader JS layer (or the opposite, or something different)

ii) Lots of libraries are extremely well documented and typed. This is the same in any language not just for types but also for docs, capability, perf etc. This argument applies to all software everywhere so it doesn't make sense to single out TS

iii) Error messages can sometimes be hard to follow. But you get better at parsing them very quickly when they get gnarly.

iv) Transpilation is nearly always a required step anyway. Adding TS support is minimal. There are plenty of tools that do TS to JS on an order of magnitude of MS.

All decisions are tradeoffs.

What benefits does it bring (ignoring the biggest one of them all)?

TS makes it easier to maintain software across large teams by providing a mechanism to express relationships in a codebase.

They are self documenting and replace a lot of JSDoc needs (letting you focus docs on more useful info like intent, design choices, example usage, etc).

Types can also replace the majority of unit tests validating code is correct saving time on running fewer unit tests and letting devs focus on integration tests.

Lastly, I've never seen or experienced something breaking from upgrading the Typescript version in a project. Even when a TS upgrade has 'breaking changes' they never actually break anything in practice that I've seen.


> ii) Lots of libraries are extremely well documented and typed. This is the same in any language not just for types but also for docs, capability, perf etc. This argument applies to all software everywhere so it doesn't make sense to single out TS

I am singling out TS because although most good libraries have documentation for all of their methods, along with examples, many useful and popular libraries do not include full documentation of their types. Some hardly any at all.

Usage examples are some of the most useful piece of documentation you can have in a library, but many authors choose to show their examples in JS, in order not to be too opinionated. It is the fact that TS is not actually part of the language, and simply an add on, that I believe is the cause of many of these issues.

> What benefits does it bring (ignoring the biggest one of them all)?

I do believe it brings benefits and agree with what you have written, of course my view is that those benefits just aren't worth the effort. In my experience some of the best codebases I interacted with were neatly written and well documented JavaScript codebases - no TypeScript, whereas many of the TypeScript codebases have been very hard to understand and work with. This is by no means due to TypeScript, however it doesn't make me think that it helps in terms of making anything that much better.

I can't even remember many times TypeScript has actually prevented a bug, it's been more useful for documentation. But then I would prefer JSDoc which isn't so difficult to maintain and can still provide autocompletion for you.


> many useful and popular libraries do not include full documentation of their types

> but many authors choose to show their examples in JS, in order not to be too opinionated

This is certainly true sometimes, but I don't see why it's a reason against using TypeScript? If you're calling a TypeScript API, the way you use it should look basically the same as the way you'd use it in JavaScript. You usually don't have to do anything special with the library's types unless you're getting fancy

There are exceptions- I've had a rough time fighting to get code using the styled-components library to fully typecheck, because that library gets super fancy with the way they represent things (I don't like it for that reason personally, but I know others do). But libraries like that are the exception in my experience, and if it's really that big of a drain on productivity, you can always bail out and use `any` types to skip dealing with it


I am thinking of the case where you are passing an object or class to an API that needs to be shaped a certain way. In this case you need to know which type to import/use to pass it through.

For many simple libraries it's not too much of an issue, but for more complex things like Apollo (which also doesn't include much TS in their docs) it's a lot of hit and miss until you get it right.


Sure, that can happen. I guess I feel like if it's that much of a problem for any given library, you always have various ways of disabling checks where you need to and still benefiting from them elsewhere. So it's still a net benefit

I will also say- GraphQL almost by nature is gonna be a really hairy thing to statically type, especially on the server side. We've got an Apollo server at my company and thus far we've pretty much just punted on trying to type that part of things. Which is also more okay than might be for other things, because GQL does its own runtime validation anyway


I agree on the "error messages are hard to follow". A lot of times when you have an error it doesn't clearly communicate "hey it should look like this" (something Rust does soooo well) and instead says something like "types or property A incompatible with property B that is incompatible with X and not Y and ....". It basically just explains the nesting but is so hard to actually make sense of or how to solve it.


> It's a framework, with all the usual framework downsides

> For example, a new package you install can require a new TypesScript version. Once installed, you then may need to update your source code. This can place quite a high tax on the developer, where perhaps a 10 minute change becomes hours long.

No. It's a language compiler. You can upgrade it safely without changing a single line in your codebase. If there is a breaking change (sometimes, regarding the strictness) there's also a configuration option that lets you keep the previous behavior.

> ii) Libraries are badly documented

And so you're going to lose any and all typing as your solution? I don't understand. Undocumented but typed >>> undocumented and untyped.

> iii) Error messages are hard to follow

I disagree completely, TypeScript has helped me many times to understand what's happening and why - I mean errors that I wasn't aware of in my previously untyped JS codebase.

> iv) It requires yet more transpilation

> Transpilation takes time, and always adds a burden to developers.

Doesn't matter. Use SWC or esbuild for sub-100ms compilation times. Your CI is a long running job due to tests and lint anyways. Nobody is writing pure uncompiled JS these days - you can't use NPM libraries that way, so there's always some (Web)pack step. I haven't seen a single developer who liked having to care about browser versions and wants to go back to that - but if you add a compilation step you get that for free and can write the latest and greatest.


> No. It's a language compiler. You can upgrade it safely without changing a single line in your codebase. If there is a breaking change (sometimes, regarding the strictness) there's also a configuration option that lets you keep the previous behavior.

I am currently stuck on a very difficult issue because of a TypeScript upgrade. The upgrade caused a type mismatch with a dependency that wasn't previously an issue, and due to the lack of documentation on that dependency I am currently trawling through source code.

> And so you're going to lose any and all typing as your solution? I don't understand. Undocumented but typed >>> undocumented and untyped.

No documentation of types means going into source code to see what is there. Sometimes there could be multiple types that could be used for something, and it's not clear which should be used. Most libraries have clear docs to show me how to use a function, I'll take that any day over the uncertainty of which type may be correct in many places in my codebase.

> Doesn't matter. Use SWC or esbuild for sub-100ms compilation times. Your CI is a long running job due to tests and lint anyways. Nobody is writing pure uncompiled JS these days - you can't use NPM libraries that way, so there's always some (Web)pack step. I haven't seen a single developer who liked having to care about browser versions and wants to go back to that - but if you add a compilation step you get that for free and can write the latest and greatest.

Not arguing for no transpilation though browser compatibility isn't much of an issue these days unless you are using some super new features of the language (the reason is more about bundling the code together and jsx as far as I understand). I am arguing that each transpilation step adds yet more config that needs to be built, understood and maintained. TypeScript is probably the worst offender, almost as much work as maintaining another webpack config in your projects.


Did you upgrade Typescript (and if so, why), or did you upgrade some project dependencies, or type definitions?

> No documentation of types means going into source code to see what is there. Sometimes there could be multiple types that could be used for something, and it's not clear which should be used.

I haven't had this experience, and I'm not super experienced with Typescript. Are you using VS Code? It typically makes it trivial to find the definitions of things I'm interacting with in the editor.


> Did you upgrade Typescript (and if so, why), or did you upgrade some project dependencies, or type definitions?

I need to upgrade it because I upgraded a dependency that needed a newer version of TypeScript to compile! And I needed that dependency to be upgraded to use a newer version of NodeJS.

It seems that the newer version of TS was more strict, and now I can't find a type from ProtobufJS that fits the code. I can update here when I understand more about this particular case, but presently my best bet is to loose some typing and autocompleting by using some unknown types :(


Did you try regenerating protobufjs and .d.ts files after upgrading?

For me it's something like

    npx pbjs -t static-module -o protos.js *.proto
    npx pbts -o protos.d.ts protos.js


> Did you upgrade Typescript (and if so, why),

What an odd question! Even ignoring new features and better type inference that comes with new versions — once you add typescript to your project, it becomes one of its dependencies. Don't you regularly update your dependencies, just as a good practice, not to let your codebase slowly rot?


> Don't you regularly update your dependencies

No. Update dependencies as needed for security patches (which typically avoid breaking changes), other than that never update unless there is an explicit business need.


Yeah, I'm with you. I have a lot on my plate, maintaining and developing the main application I work on single-handedly, while also working on several other projects, and putting out fires elsewhere in the company as needed.

I don't have time to spend days to weeks figuring out why upgrading Tailwind to version 3 breaks the project because of (presumably) my version of create-react-app.. do I need to eject, or copy the .ts/.tsx files over to a Vite project? Do i want to fuck around with CRACO, or editing the internal monster of a webpack config file directly?

Yes, critical security updates are important, but you shouldn't just go around upgrading major versions of other packages in your production app, without the understanding that it might be an incredibly time-consuming endeavour.


I am the opposite. To me, dependencies in a project are a debt to which I regularly make my payments by keeping them up-to-date and resolving breaking changes as they arise. Allowing dependencies to fall too far out of date, in my experience, made updates — when they became necessary — too painful.


I agree with your comment, however please don't make new accounts just to respond to a single post or comment, judging by your username.


Couple of years working with TS and I think I can add my 5 cents here:

1. It is worth it, but not as much for benefit of types safety straight forward as for ... "intellisense" that discharge you from remembering stuff and misspelling it

2. It is annoying - they (MS/TS team) have very "conservative" approach which leads to:

  - no operators overloading, 
  - no option to extend primitive types, 
  - no option to get info about your types at transpile time, 
  - no built in options to improve performance at transplantation time,
  - no built in options for transformation plugins
  - no other than JS transpilation targets
  - need of tons of other tools to make your actual target, 
  - ... etc. 
At the end it does job well, but only because you put in it a lot of man hours (to learn, develop and maintain) - and everyone seem to be happy about that.

Sorry for being a bit grumpy, but sometimes it feels like wasting a life working with TS. ;-) (especially when I read again what I just wrote ;-) )

Seriously, let me know MS/TS team if you need someone to drive to TS some real fresh new value ;-)


After years of Flow, Typescript, Webpack, React, JSX, etc, I went back to just vanilla HTML, CSS, JS for my most recent production project (https://play.d2lang.com, which is open source). The experience was great. I didn't find myself missing any of those tools.


Just curious - how many developers worked on that project, and for how long?


if you're talking about the playground, I did the initial version in a weekend or so (https://github.com/terrastruct/d2-playground), which includes building a WASM version of D2 (written in Go), putting a text editor, some UI stuff like dropdowns/menu, hooking it up together, layouts and responsiveness whatnot.


For me, TypeScript is like putting lipstick on a pig. It improves one thing about JavaScript while leaving all the numerous other flaws and introducing new ones.


If you are doing JS then you should certainly be using Typescript.

The best choice however is to simply use a better ecosystem entirely.

IMO JVM+Kotlin is great general purpose combo, Rust is good if you don't write the sort of code that needs GC'd structures, etc. Between those two I rarely need to consider anything else.


I find TypeScript very helpful! As a self taught developer I always used to just use JavaScript, but after joining a big company and working with TypeScript I prefer it now. I like how I always know "what's in the box" now when working with different objects and whatnot.


I think you need to be very careful there. Only because something is, e.g., a number, does not mean you know what it represents. I think Typescript might actually create a false sense of safety.


One of the biggest mistakes that I see devs making is caring too much about making TypeScript happy when they know it doesn't really matter.

There are a lot of cases where it's totally reasonable/rational and honestly fairly safe to just throw in a well-scoped "any" cast, a `// @ts-expect-error` comment, etc.

If you know what you're trying to do, and TS isn't understanding, sometimes it's just a lot more expedient to tell it to shut up and listen to you.

Of course, sometimes you're wrong, and you don't want unsafety to leak, so it does require a fair amount of experience and judgement to do responsibly.


This feels like telling Haskell developers that they should use unsafePerformIO and unsafeCoerce more.


It's much more like reminding TS developers that Go developers have to use `interface{}` all the time, because some types are actually hard for compilers/typecheckers to deal with.


Maybe? Occasionally telling ts to shut up or lying about types is better than not using it because you have a hard time getting 100% type correctness.


TIL: `@ts-expect-error`

I've been using ignore a lot and leaving a comment.


If you write a project for yourself, or develop a startup or an MVP it's often not worth it.

Late-binding dynamically typed languages are underrated, if you can hold the mental picture of types in tour working memory, that is.


There's elm, a statically-typed language with none of the pain points you described. So my short answer is: Compared to javascript, yes, it's worth it. Compared to elm, no.


The answer to "is {{tool}} worth it" is almost always "sometimes"

Typescript is a wonderful tool for many situations. Typescript may not be needed for all situations. There's upfront cost to configuration and tooling. But you get type safety and automatic documentation.

In all my new non-trivial projects, I default to typescript. It has caught so many issues and saved me a lot of time. Not having it feels like driving without a rear-view mirror. But, if I'm just writing a little script, I might omit it.


For ii.) Typescript is a superset of javascript. If it annoys you to try to translate JS documentation into TS, then don't. Just use the JS example and use ts-ignore or something similar. Why throw out TS when you can literally suppress those one-off instances?

iii) You should see C++ template errors if you think the TS errors are bad. The TS errors do suck sometimes, but when I see which line of code it's complaining about, it's usually enough to clue me in to what the problem is. And once again, ts-ignore exists for a reason ;)

iv) The majority of the frameworks I use allow you to skip transpilation while developing. So you can supply the TS files directly, and then transpile when you're done.

TS has some problems sure, but these all seem like very surface level complaints that you have to deal with in any other language. Which language has dependency management solved? Or clear and concise error messages all the time? Or super fast compile times? I don't see any alternatives that don't host some or most of all of these warts.

Additionally, when I code using Javascript I feel like I'm blindly groping my way through the magical forest of dynamic code. Typescript gives me a clear and concise road map and helps me avoid a lot of traps laying around that are obscured by that dynamic magic.

Is typescript worth it? 100% yes.


There is a big issue with “suppressing one off instances”: the truth is you’re either fully bought in or you’re not. If you have “any” types or ignores littering your code base, you don’t have type safety, and at that point, why even have typescript? There’s not _really_ any such thing as being “mostly” type safe. You could argue that “this part of my code is type safe” but if it interacts with any other part of your code that isn’t, then what’s the win?


Your code is going to run on a computer somewhere. It will never be completely safe. And many kinds of error will escape even full detailed types.

Mostly safe is useful. The more you tighten types, the fewer errors can occur.


My problem with typescript is that at the hands of a typescript aficionado the code is nearly impossible to read.

It requires so much mental effort to understand what's going on


The way I think of this is, if I were running a small team as lean as possible and trying to grow as a business, getting as much out of expensive developer time as possible, my answer would be that I get productivity gains sometimes from the work put in to strictly type inputs and outputs to/from functions, whether they be props on react components or whatever. Otherwise, largely a massive time sink that I'd be pissed I'm paying for.


I've used TS since it came out and it's always been great.

There are a few quibbles with TS devs over not implementing certain ideas because it breaks out of the JS superset paradigm, which really makes me wish we had a TS++ or TS# that broke this on purpose but hey.

It does have a lot of problems, but it usually comes down to pre-existing ones. i: yup but like, isn't that true of every framework/language/library? But less so for TS given that it's open source

ii: this is the JS ecosystem in a nutshell, but I think you'll find with any similarly sized ecosystem, built from the thankless efforts of a bunch of amazing individuals in the community that this is true. If you want Oracle level support/docu you gotta pay big $$$ for it

iii: this is very true and my advice to other devs I work with is usually to read more towards the bottom of the error. TS currently gives you a lot of context for the error, much of which may be but isn't always useful.

iv: realistically we have been waiting for a very long time for node.js/browsers to be able to run TS natively. I would be a huge fan of this. Transpilation on large projects can take a good amount of time, but I'd say the larger the project the _better_ the advantage you will have using TS; sure you'll have to deal with trans times but TS can really save your butt when making a breaking change in a large project.

I've used Node.JS pretty much my whole career, whilst I've done a lot of stuff in C# and C/embedded as well my mainstay has been Node & JS and as soon as I could use it, TS.

I remember callback hell, I remember adding console logs every few lines to figure out what the fuck is going on, I remember sitting in the debugger trying to make sense of why various vaguely connected chunks of code weren't working properly. I've seen things you people wouldn't believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhäuser Gate. All those moments will be lost in time, like tears in rain.


I love TypeScript in the right places, but I think it’s often used for things where other tools would be a much better fit.

On the backend it can be nice if you’ve got a monorepo including the front ends it supports. Maybe you’ve got graphql happening and you can share types. That seems great sometimes, and there are cases where it’s super handy and efficient.

I don’t know for sure, but it doesn’t seem worth it after a certain point. I’d much rather keep typescript to the front end where I find it really shines. I’ve worked on a lot of projects where it was full stack typescript and there were always these common, nagging, very typescript-and-JavaScript-specific problems.

Fundamentally the build and development tool chains in general tend to be awful. I can accept it on the front end out of necessity, but on the back end it gets egregious quickly unless you’re using micro services and builds stay quick by default.

Any time I work on something statically typed with nice tooling I realize how much better life can be. It feels like the minor gains I get from fullstack TS are quickly negated by the plethora of advantages to using something like Go or Rust where I can purpose-build applications with absolutely crazy performance, reliability, and portability.

So, TS in the browser is awesome. I think you’d be crazy not to. On the backend on the other hand — unless you’ve got like a perfect fit for using something like Next.js or a static site generator where the backend can be dead simple, I’m pretty tired of dealing with its deficiencies.

And even then it’s not the language so much as the cruft built up in tooling over the years. It’s slow and awkward. NPM is plain old awful. Basics like linting are painfully slow. Testing libraries feel like a house of cards. And so on.


There are alternatives to NPM, and high performance build tools. A lot of code-quality tools like linting are on the slower side though.

Ultimately people use TS on the back end because they want to simplify hiring and reduce context switching loss in developers mostly, and in some cases because their application is isomorphic. This choice works well when the ratio of front end to back end code is high (which is the case for most shops), since these benefits outweigh the downsides of developing services in Typescript compared to go (I wouldn't write most services in rust...).


> Ultimately people use TS on the back end because they want to simplify hiring and reduce context switching loss in developers mostly

In my experience this hasn’t panned out particularly well, but I believe it works for some teams.

> because their application is isomorphic

This is one case where it had worked out okay for me. The scope has tended to be relatively limited and there was a framework in place which was generally good at gluing things together and ensuring people work along the same rails.

> I wouldn’t write most services in rust…

No, me either. I tend to teach for Go for web services these days, but I do like rust for CLIs and situations where optimizations are crucial. Admittedly I don’t even like Go as a language that much, but it’s great at what it does if I’m willing to put my head down, deal with the quirks and verbosity, and crank something out. It’s not a language of cleverness or elegance, but the results tend to be excellent and easy to maintain.


Ok so I finally created an account just to respond to this post because I wanted to share my experience with typescript. I really don't get the confusion and doubts about the usefulness of typescript. It's my favorite language to use because of it's expressiveness.

In my company we built a lot of web apps in very small teams (mostly just 2 people). We use mostly c# as a backend and typescript + mostly angular, sometimes react as a frontend. When typescript came out I built a conversion utility that allows me to generate typescript definitions and metadata from my c# type definitions. In angular I built my own type safe reactive forms, access control and API framework. Often we use ef core as a database layer on the backend, so we have a single source of truth (the c# types) for database and frontend types for the API. I use mapped types in typescript a lot to reuse the generated API types in my frontend code. If a field in a class is renamed ef core takes care of the database migration. On the frontend I get notified of every error because of the rename. Is there a table column for the field, I get an error. Is there a form that maps to the field I get an error. Do I check for write permissions of the field with the old name somewhere, I get an error. I use exhaustive matching to ensure that all cases of enums or union types in general are handled. Everything is type safe and the types come from a single source of truth.

It's so insanely productive it feels like magic!

Edit: also wanted to add I mostly do not use libraries outside of framework libs for angular or react in my frontend. Generally most library code I need (with few exceptions) is built by myself rather fast and easily. I avoid libraries because of the npm ecosystem mess but it also has the upside that I don't have problems with outdated type declarations or typescript incompatibilities.


Hoenstly, for production code, TS makes me sleep better. No matter how many tests you write, that one undefined object will get you at some point. TS helps to eliminate a complete set at compile time (as you know) and that's great!

Anecdotal evidence from my Haskell experience: If my Haskell programs compiled, they usually worked. Which is amazing. Powerful types for the win.


> Anecdotal evidence from my Haskell experience: If my Haskell programs compiled, they usually worked. Which is amazing. Powerful types for the win.

I have the same feeling regarding Haskell, Elm and Swift, the latter I program in 99% of the time. I really don't feel like I get the same sense of security from Typescript, to be honest. Maybe I'm not using it correctly? I tend to lean more towards OP's opinion. I would probably prefer something like Rescript, but haven't looked much into it.


Rescript and its standard library Belt are great. I have been using BuckleScript/ReasonML/Rescript since 2018. It gives better guarantees than TypeScript and has a stronger focus on the functional approach to problems. The only drawback is it has less documentation than TypeScript, and you will likely have to write bindings for JS libraries you want to use.


Thanks for sharing, I'm definitely going to dig into it more.


I agree Typescript doesn't give "if it compiles it works" but it does give "if it compiles there aren't totally noddy errors like typos". And it gives you a codebase that is understandable and maintainable which JavaScript does not.


I get your point, but it actually increases my productivity. Some examples:

I no longer have to worry about things unknowingly becoming undefined or falsey.

When chaining map, filter, and reduce, I know at every step of the way what kind of object I’m working with.

And when I use a dependency, I don’t have to trust possibly outdated documentation but can rely on types.

Just these three things make it 100% worth it for me.


"Thank you, TypeScript." < something I have said sincerely on a few occasions.

"Thank you, JavaScript." < something I have said sarcastically on many occasions.


I don't think (i) doesn't make sense to me... I guess a package could foist a TS dependency on you but it certainly doesn't have to. It's pretty sloppy if it does, so maybe not the greatest package anyway. (ii) has nothing specifically to do with TS. (iii) agree. (iv) sure, though static type checking requires a static type-checking step and tool.

You started by skipping over the benefit of static type checking, but that's the direct trade-off: is that benefit worth the extra complexity and time spent satisfying the compiler. For me it's probably usually yes for smaller projects where I know the devs can handle it and definitely yes for larger projects where the communication burden is high (it just partially helps people stay on the rails, organized, and on the same page -- not sufficient by any means, but it eases the strain).


My biggest problems with TypeScript are that it regularly gives me null safety bugs even after I add guards. And I can't really trust the types typescript offers.

I've been using typescript for a year now and I just want to go back to Java at this point. Biggest obstacle to that is management believe it or not.


> i) Like a framework, you are at the whim of TS devs as it gets updated (edited)

I have been using TypeScript for almost 6 years and not experienced this problem. Like everything else keep things simple, don’t chase trends, and so long as do right by your product everything will be smooth. I also don’t waste time with large SPA frameworks.

> ii) Libraries are badly documented

I don’t use many dependencies. The DOM and Node type definitions are extremely well documented and inspired me to write better documentation.

> iii) Error messages are hard to follow

For me this depends on the complexity of a given object or type definition. When things are primitive the error messages are more clear. My only suggestion is to keep your interfaces primitive.

> iv) It requires yet more transpilation

I use SWC as a TypeScript stripper. My nearly 50kloc project takes about 2seconds to covert to JS, which pushes out my total build time to about 2.5seconds.


To me it's worth it because as opposed to languages designed to be strictly statically typed, the type system is there to serve you, not the other way around. It's pragmatic and tailor made for its use case.

People who've always programmed in traditional statically typed languages like Java scratch their heads on why would anyone not want to have static typing, but the reason for that is simple: in a dynamically typed language you can (and often do) produce code that's hard or impossible to type in said statically typed languages.

TypeScript's designers recognized this, so not only there are escape hatches here and there, but also the type system over time evolved to adapt to the real-life use cases instead of imposing some abstract, complex type system which might not even be very useful when used against all the creative ways JS programmers write their code.

And it works.


Personally I moved over to Rust for as much as I can.

I still use TS on frontend (as frontend framework in rust are not quite there yet when compared to something like solid start - perseus is getting there though) but I definitely use any freely when I'm in a hurry.

That's exactly what I don't like about TS: it enables developer to bypass safety making the whole thing not very safe. You can't trust your dependencies as you normally do with Rust (unless your dependencies specifically opt out with unsafe - there is still deps vetting needed, but it really hasn't been a problem).

Is it worth it? Before swc I would say no, with swc (typescript compiler written in Rust) the perf hit and DX is not too bad and I'd say yes.


I'm with others (it's worth it when there are more people / the code needs to be correct), but the example of Protobufjs is unfair: I expect it to be super complicated to work well with Typescript. TRPC is growing for a good reason.


I've come to TS from Python.

To me, install a new package and it requires "target=ESNext" and modules="ES2022" and suddenly I feel like I'm back in the Python 2 to Python 3 transition debacle.

Except this happens every couple of weeks!


We recently brought a large js project from js to ts and, while we had issues, almost all to do with transpiling and the obvious end result being javascript which is not typed. Coming from f#/c#, and having used Purescript, typescript feels familiar, however, it takes too much from js imho. Especially the automatic coercing is pretty annoying to us and still causes pain we would not have in the other languages mentioned above, but it is miles better than js. We can refactor much faster than we could before.

We definitely are happy with the move. I will never be a fan, but the alternatives I cannot sell to the team.


I think what you've done here is document the pain introduced by using TypeScript, but you've not documented the (unknown) pain from not using it.

The question should really be, are the development pains you have more or less than the (most likely) production pains you'd see if you weren't using it?

I personally believe that more problems in development for reduced production outages is the right answer for the vast majority of software development.

If would be interesting to know of cases where projects have stepped away from it. I'm sure there are some examples and it would be interesting to understand their reasoning.


For me, the main problem is that TS doesn't follow semantic versioning and this leads to a fragmentation of libraries support - unless they also provide multiple type definitions (some of them actually do) - and migrating to newer versions is usually harder, because breaking changes happen so often. So I guess point i) is correct.

Let's see the others.

ii) It's true that many libraries don't have type definitions, but the most used ones have an externally-maintained corresponding @types/### package that solves the problem. And even if they don't, how is it the fault of TS? The alternative is no type documentation at all - is that better for you?

iii) Yes, error messages are something that can be improved, but then again, the alternative is no static error and eventually an even more laconic runtime error. Would that be better? At least, TS catches that there's a problem before you run the code.

iv) Compilation adds a burden to the CPU, not the developer. But anyway, it's a one-time process, and unless it takes 30 minutes it shouldn't be a problem. There are new, much faster compilers nowadays, like esbuild and SWC, plus other tooling tricks like module caching, that makes your local development almost feel like there's no compilation at all.

I won't discuss the merits of the adoption of TypeScript. Since I started using it - except for very simple projects - I always felt like I'd be way less productive without it. And I actually had the confirm recently, when I had to work on a Loopback@3 BE that somehow is in JavaScript (even though Loopback 3 does support TS).

It's been a mess. Trying to understand the models, the signature and the sense of all the entities has been a nightmare. The documentation for LB v3 is badly maintained and sometimes broken, and this adds even more difficulty. Some dev tried to add some JSDoc info here and there, but it's not nearly sufficient to understand what's going on without investing hours of study of the existing code.

This is part of the cause that prevented the team to upgrade to LB@4, so much that I even suggested to redo the BE altogether in Nest (save for the core business logic parts), rather than trying to make a sense of it.

So yeah, I'll stick to TS for the foreseeable future, and strongly suggest all the teams I'm going to work with to do the same.


I've seen "we can't get OpenAPI to automatically generate our types in a sane way" derail a 3 month project to standardize an API". In 20 years of js, I never had that problem. YMMV


In a word: YES.

Update TS regularly to avoid making updates hard and lagging behind to much. Unlike a runtime framework, updates are unlikely to break things at runtime, so there are no reason not to update very often. If some external types are wrong or annoying, don't forget _any_ exists and simply brings you back to the crappy situation you'd have without TS (well admittedly it adds transpilation costs, but it's still type checking everything else, which is well worth it).

I think TS is nearly the best language that could be done given the constraints of being fully compatible with JS.


What I read is static typing is a good thing but the costs of using it in TS aren't convincing really.

I feel that using it optionally where it's easier to maintain and feel its value is the best of both worlds.


I write types everywhere. Without types, I'm in the blind. So yeah, don't look at motifs why some library maintainer has TS errors in their declaration files. I'm a full-stack TS developer, and I can count on my one hand fingers the times when some library had type problems. And if they had, I would fix them with my own declarations. But how do you code without types? It brings so much clarity to everything. Judging by your questions, you haven't worked with TS a bit. Or you like sensational HN titles, drawing in all the kids lol


I've been continuously frustrated by it - but the projects I'm working with are large, or leverage some more complicated dependencies. For example both ProtobufJS and Apollo can be very tricky.

I also do a lot of refactoring and improvement on these codebases, often updating packages, so perhaps I run into more issues more frequently than many. I accept that a lot of the time it can be smooth sailing, but anything tricky and it's a real time sink.


For the most part, I only hear from typescript when there's a type mismatch.

Understanding the type mismatch is ofter difficult, but it does solve a real problem.

I also like that it gives escape hatches, for when I know what the type should look like, or I don't care what it looks like

I haven't found the typescript updates to be difficult, nor situations where packages I'm depend on require incompatible typescript versions

My pains are on that it's hard to get the setup right where you aren't depending on a giant set of types packages, giving you size bloat for things you mostly don't care about.


I would say, as a person who have been developing in JS/TS daily for the last ~5-7 years that it depends on your team.

If you have a larger team, yes it is worth it. If it is your side project or if you are like 2 people working on a project then I would say it's probably not worth it.

Typescripts biggest strength is that it's easier to work several people on the same thing. When someone else makes a change, it's easier to figure out what their code does.

The bigger the team and project, the bigger benefits you will get from typescript. At least, that is my opinion.


> If it is your side project or if you are like 2 people working on a project then I would say it's probably not worth it.

I have several frontend side projects and they all use TypeScript. The static types makes it way easier to write & refactor even if you're working alone. I have also more confidence in my code and spend less time following JS trails to track stupid runtime bugs. Older projects are easier to pick up again.

Any project that goes beyond a few trivial files will benefit from Typescript.


Oh, thank heavens! Finally someone says the quiet part out loud. I thought it was heresy and that the TS bubble would never pop. From my perspective, it's not worth it at all. It's just another hype train. It doesn't prevent bad programmers from writing bad code, nor does it cause good programmers to write better code. It mostly just adds bureaucracy and hindrance, in the ways you allude to in your list. It doesn't make hard things any easier, but it makes easy things harder.

It's also way too complicated for what it is. To the extent static typing is beneficial, most developers and projects only need the bottom 30% or so, but the expansive - and expanding - feature set encourages byzantine solutions, especially for showy types for whom tight little chunks of terse syntactic cleverness are an aesthetic (I've been there, I get it). And as if JS build tooling wasn't unnecessarily overcomplicated already, let's pile on a bunch of transpilation infrastructure?

Now, I still use TS, having sensed that it's where the centre of gravity was moving as far as JS developer fashions. Plus, of course it's not bad to have types in the language in a rudimentary sense. Sure, why not? Moreover, I try to pick technologies that I could hire someone else to work on or collaborate with me on in the future, and TS is definitely "in". There were subtle nudges from other areas; I'm a very heavy Vue user, and Vue 3.x certainly doesn't mandate TypeScript, but let's be real; they want you to use TypeScript.

I make a point of using as few "clever features" as possible; 90% of my uses are banally simple interfaces. I think I did foray once into `Map<Partial<keyof RTCSessionEventMap>, RTCSessionEventMap[keyof RTCSessionEventMap]>`, and it's not at all clear that this got me anything. But it looks cool, doesn't it? I guess that's what leads TS-heavy developers to churn out impenetrable gobbledygook. I'm quite capable of not typoing my own key names. Why are we so fixated on abstruse manipulations of arbitrary contrivances that get transpiled away anyway? I suppose you could ask the same question about any high-level programming language insofar as it ends up machine code in the end, but TypeScript's complexity doesn't reflect an appropriate humility for its place high up the meta-hierarchy. You need to be an actual programming language to ride this ride; as a fancy templating system, it's too entitled with its massive cognitive demands.

I'm not going to say there's nothing good about TS. I do appreciate the ability to inspect type definitions to learn more about how a library works, especially if they have crappy documentation--which is often. Naturally, I also pocket the benefits that type definitions afford to IDE autocomplete. But on the whole, it's a drag on my productivity, and I spend an awful lot of time either struggling to decipher someone else's TypeScript or paying some sort of tribute to the exacting and mercurial TS compiler gods. I'm not writing better or error-free code because of it. Good end-to-end testing is a check on my code quality; the ever-so-occasional squiggle in the IDE is not.

Related thought: "type safety" has become some sort of metaphysical fixture, an unfalsifiable theory of quality and robustness. "I'm so glad I have type safety!" is a liturgical or ritualistic statement, the kind that nobody in their right mind would question, or attempt to unpack or otherwise anatomise. It's a self-evident, ipso facto good. Types in JavaScript seem to have become a religious totem object. This oft-posited but seldom materialised correlation between "types" and "quality" remains to be illuminated for me. My background is entirely in statically typed languages (C above all else), so I understand the argument and need no convincing that types are good, and even elegant. However, I can assure you I wrote plenty of buggy code in C, C++, Go, Java...

It reminds me a bit of the apex of the TDD hypermania about "refactoring with confidence", or specifically, the naive and childlike optimism of "now that I have unit tests, I can refactor with confidence!" Can you? That depends on many things, doesn't it? Truly, how could it not? And either way, an overabundance of confidence owing to some platitudinal methodology is generally not a great vantage point to bring to engineering. Humbleness about breaking things keeps satellites in the sky, not euphoric, LSD-fuelled campfire paeans to TDD, and certainly not the mere presence of types. </rant>


Yes, 100%. This is exactly how I feel about it - and the idea it has become some unfalsifiable religious ideology is particularly poignant. It's such a drag on development and personally I just don't see the upside that much, just some assertions from people that seem to be repeating something they've heard elsewhere without much experience weighing in on the discussion (except for autocomplete and self documentation which imo is the best part, although could be replaced by something like JSDoc).

Sure, I'm okay to live with TS, and it has its uses, but I thought it was about time we had a discussion about how much harder it can make development.


> The type definitions exported by these libraries can be large and complex, and the error messages emitted by TypeScript are so long and cryptic

What’s the alternative? If you make a type error in TS you get a cryptic error[0], but if you make a type error in JS you get a bug which you learn about after it crashes prod…

[0] Personally I rarely get cryptic errors, because I go out of my way to design libraries in a way that the type definitions are kept simple, which also has the benefit of keeping the mental model of how the library works simple ;)


My biggest fear with TS is people forgeting why TS exist in the first place and stop trying to solve the problem TS solves because it's already solved. It's not solved, TS is by far the best option, but its far from being ideal. Deno coming out of the box with TypeScript support and the JavaScript Type Annotations Proposal [1] gives me faith that we will grow past TS.

[1] https://github.com/tc39/proposal-type-annotations


You can't believe from how much bugs TypScript has saved me. When it was "first released" (when it became more popular), I have ported our starter kit to TypScript and was amazed on how much stuff it was detecting as not safe.

Since then, I can't image working without TS. As for Third Party libraries, I have a different experience from other devs here, it works very well for most (if not all) big libraries/frameworks, and the autocomplete saves me so much time in digging in the docs.


Typescript is great but be aware that sometimes it can annoyingly slow you down. Consider these scenarios:

- You want to use a third party library but it is completely untyped - You need an object but you're just prototyping it. You don't yet know which keys will be optional - You type a key of one of your objects. Now you load or fetch data from an API and want to assign that to it. But typescript complains because the promise can also return undefined. - and many more

Just be aware that it will annoy you at times.


If you don't know what parameters are optional, just add the little question mark to every variable and remove the ones that turn out mandatory? Better to have some type info than nothing at all.

If you fetch data and TS tells you the result may be undefined then I guarantee you your code would've randomly crashed at some point in the future because of it. That error is a feature, not a bug!


I am aware of those. I am just saying that it will slow you down or annoy you. For me, sometimes I am pretty much prototyping code just to see how something works. Once it does, I'll do it properly.

Then I have to e.g. check if all keys of an object could be undefined before i do something with them.


You can also toss on an exclamation point to insist it's not null, and come back later to clean those up.


third party libraries can be a pain even when completely typed, if their types rely on complex inference, are really complex, or make heavy use of subtyping


I like using Typescript in general, but sometimes it becomes painfully obvious that it's Javascript with type checking added to it at a later time. So I actually kind of which there was a language I could use instead which is typed from the ground up and requires less boilerplate, no painful syntax and provides more extensive type checking. But of course the major downside would be that it becomes hard to mix that with plain Javascript.. Also due to its popularity I think this is the least of all evils.


i) You could say the same thing for the underlying language: EcmaScript has evolved so much in recent years that new packages may use runtime language features that are not supported by an older interpreter runtime.

ii) You could argue that types themselves can be documentation, if named correctly. A JS library without types but great documentation is vulnerable to implementation changes that are not reflected in the documentation. TypeScript at least binds the internal assumptions on function arguments and object types to how they should be used, with a tool to check that there is a match at the call site. Throw in some runtime parsers (eg: Zod) to enforce correct input data at runtime, and from which types are inferred, and you are golden.

iii) Agreed, 100%. Some people are making tools around that, see Matt Pocock's Total Typescript error explainer extension in VSCode: mattpocock.ts-error-translator

iv) Agreed again. Transpilation itself can be fast with modern tooling such as SWC or esbuild (or derivatives). Type checking is still the main bottleneck, though people like Donny (@kdy1dev) are working on a Rust-based alternative.

https://www.totaltypescript.com/rewriting-typescript-in-rust


No. It doesn't fix any of the problems with JS and it introduces a lot of new ones, namely static types. Also just way more typing, but I suppose that's literally in the name..


The part you would like to skip over - the static typing benefits - is exactly where it provides the most value and that makes it worth it for /me./ Warts and all. I'm new to TypeScript so take it with a grain of salt. I agree with some of your thoughts but I see a lot of these same issues in a lot of languages and frameworks. I'm really enjoying typescript. I'll probably be a little more jaded here in a few more thousand hours of working in it.


I'd like to hear from anyone who has issues with typescript as a build tool, either via `tsc` or an integration via something like `rollup`, what issues are you having? How often?

I have not found, even in really large projects with thousands of files, that its been an impediment to anything.

My general disposition is the whole "anti build tools" moment is a bit overblown in practice, and I'm always searching for valid counter evidence of persistent issues that can't be easily overcome.


I don't like Typescript. I just like it more than Javascript.


Typescript was only not worth it when your core framework (e.g. react/vue) wasn't native ts and also didn't have ts support.

In my experience, any npm library I try to use either already has community created types provided, is too simple to really need types/extra docs, or the docs will still be pre-es6 (pre important, pre async/await, etc.) so it's not like it was going to be convenient to learn anyways.


v) It adds so much extra complexity.

vi) You trade a few type bugs that are easily debuggable and avoidable for type composition and hierarchy bugs which are hard to find.

I have seen good examples of TS that make sense and made to play with functional paradigm, but in practice it was always a bloated mess of OOP JS introducing heirarchy where none is required producing components that are too-tightly coupled and resistant to change and slowed down developing for at least x10.


In my perception, TypeScript was initially designed to bring more people from Java world to web programming, and it sort of spoiled them, encouraging bad practices and avoiding to learn proper JS. I think TS has never really leaved that niche.

True JS programmers are still living without TS, and TS programmers haven't evolved into some culture which could compete with them. That makes TS-based solutions inherently worse.


TypeScript is great for what it is, and definitely worth it. It is like JavaScript, just better. Just don't go overboard with types, because you don't get proper guarantees anyway!

I am not using many third-party libraries at the moment, and mainly develop my own, so I am not really running into any of your pain points. For my own libraries, developing them in JavaScript rather than in TypeScript would be just plain stupid.


Something that might help is creating typed / untyped boundaries. Wrap a (possibly untyped) library with your own (maybe incomplete) typed wrapper. Then let Typescript check everything up to your particular boundary and ignore everything afterwards.

It's on you to make sure you're not misusing stuff at the boundary, but less hassle to get set up and always something you can clean up later.


I find ReScript (https://rescript-lang.org/) fundamentally better than TypeScript. It has easy FFI and a sound typesystem. With Rescript you wont have any runtime errors, like you can with typescript. But compared to vanilla javascript typescript is a big improvement.


I don’t mind it, but I do I think its a stretch to consider it a “skillset” that I need to pass memorized questions about when joining a company

its like, just there. I hate how its existence dilutes the javascript community’s example code for some libraries.

I find it cleaner than just JS but its pretty easy for me to keep up with value inferred type in just JS

I would write my new projects and tests in Typescript


You're at the whim of the crap dependencies that you choose to use in your projects. If they don't document their code or if they force you to upgrade your tooling, it's not the fault of the TS team.

I try avoid 3rd party libraries very aggressively and I don't have half the issues people talk about in front end dev. My normal set up is angular and go.


One pitfall i've found with TypeScript is getting too clever with type definitions. Too much abstraction can end up eating up a lot of time (especially with a large team). This happens because as you say, the error messages are verbose and hard to follow.

Once we started keeping our type definitions small and simple we've found it's hugely beneficial.


Very much right. If the TypeScript team created basic typing without endless permutations of infinitely clever ways to create composable type hierarchies, I'd like it more.

The problem with the endless permutations of infinitely clever ways is that people actually use them. You end up with shims and meta-shims and meta-meta-shims and adapters to turn this unwieldy behemoth into that one in just the right place. Very soon, you get something like Kubernetes, in the sense that the entire structure is imperiled by the weight of its own complexity. <ducks>


I don’t think TS is worth it, because I don’t think gradual typing provides a good cost/benefit ratio.

If I’m going to write a bit of JavaScript, I’ll write JavaScript with the minimal feature set possible. It’s not a good thing that the language has continued to accrete features.

If I’m going to write something non-trivial, I’ll go straight to Elm — an actual sane language.


I pretty much deplore using Typescript for fast paced UI development.

I will be using vanilla Javascript in my own projects for the foreseeable future.


TS is okay-ish.

The main thing that makes it shine is refactoring.

Besides that, the reast isn't that mind blowing.

I still get crazy bugs just like I did in JS, TS just removed the countless small and easy to fix bugs. Which is good, because they can really slow you down. But when you get something ugly, tests and experience are the only thing that saves you.


I can't imagine not having static typing. Maybe I am a bad coder but there is no way I would be able to catch some of the spelling mistakes, objects that are missing a property, etc. I am not sure how people catch these mistakes other than just getting value errors or doing unit tests for the smallest thing.


"ii) Libraries are badly documented"

It goes both ways, a counter example which saved me from some frustration: plotly.js has a horribly bad online documentation, but their type def makes it super convenient to explore all the layout config stuff, when you're buildling a custom visualization.


TS can be a pain. I know, I fight with it all the time. That’s probably my fault though. I’ve learned typescript by being exposed to it in our code base, rather than properly learning it through documentation.

For all the struggle, it makes me feel very confident about the code, and its reliability. That’s worth a lot.


There seems to be a lot of bespoke choices when setting up TS which have to be weighed up.

For example:

tsc? webpack+plugin? eslint?

And then all those compilerflags. Especially module targets.

Then monorepo considerations: lots of options.

Then how to generate your .d.ts files if it is a package you will publish.


Another point is that Typescript is most powerful when you use it everywhere and share types. E.g: Between frontend and backend API. It’s hard to keep track of where something is used when you change it. Typescript can do it for you.


I honestly can't see how anyone can get anything done without static typing, for anything other than small scripts.

My only issue with TS is that there are no runtime type guarantees. That, and a few odd syntax choices that I mostly don't have to deal with.


What is the alternative? If it' javascript, then no it is not worth it.

If you're talking about general backend languages, then there are a lot of options. Since you're talking about large scale applications, that likely means you can use something like java or kotlin.


TypeScript feels like it's trying hard to become Java Enterprise level of complexity :)


I think that's right. I was thinking about that as I composed my own reply to this thread: it's got many of the hallmarks of J2EE.

That is to say, it's got features that a thoughtful CTO in a very large organisation somewhere, somehow has a well-articulated and nuanced use-case for, but it's not you and it's not anyone you know. And there are a lot of such features.


I have been writing lots and lots of TypeScript in the last 5 years.

Going back to JavaScript just feels...wrong.

TypeScript isn't a perfect language, but I also feel like most of its shortcomings are related to the aim of being a JS superset.


i) Never had a problem with this, although I use very very few libraries, so that might be why. (At this point basically only preact)

ii) Yes, but this can't be used to favor JS instead. If a library is badly documented, you're going to have a hard time whether using TS or JS.

iii) This is true, but it depends on what you are doing. One advice is to avoid defining complex types. Another good measure is to sometimes suppress type checking on a few lines that you know are correct but are near impossible for the compiler to verify.

iv) I use esbuild to compile, and have a tsc -watch window open all the time.


"... is with the amount of extra work it places on developers, much of it the "dumb" kind of work which can eat up hours and doesn't deliver all that much value."

that sounds terrible.


Absolutely worth it. The benefits far outweigh these downsides, and I’m surprised someone who’s been using it for two years doesn’t agree.

I would simply refuse to work on a JavaScript project at this point.


I choose to avoid typescript for most of my projects and teams. There are some exceptions.

I have some fundamental guiding principles I apply to engineering, and I find that TypeScript violates these:

1) Reduce complexity

2) Don't be clever

3) Achievement over activity

4) Longevity

---------------------

#1 Reduce complexity

---------------------

Cross compilation introduces additional complexity with debugging and production support. Sourcemaps work fairly well, but often fail on edge cases - normally where you want to be debugging. I've found that JSDoc with good tooling gets 70%+ of the benefit of TypeScript without the additional complexity of cross compilation.

In the browser Javascript ecosystem, I aim to have what executes in the browser be as close as possible to what I've authored. Typescript works against this goal. This is even more important to me on the server side, where introducing a build step diminishes a lot of the value of having a flexible, dynamic environment like Node. If types are desired on the server side due to needed formalism (several problem domains are like this - banking, etc...) there are other languages/execution environments that may be a better choice.

------------------

#2 Don't be clever

------------------

Clever code is frequently a maintenance nightmare. Code should be clear, readable, and approachable. It should tell a story that's easy for anyone (even semi-technical folks) to read.

Typescript lends itself to "clever" and arcane types & structures that increase cognitive load and decrease maintainability, especially as the rules change.

----------------------------

#3 Achievement over activity

----------------------------

I guide my teams to focus on delivering business results and shipping software. I've seen code bases where up to 40% or more of the total LOC are nothing but types and structures to satisfy the compiler, not to provide features. In some cases, that's a good thing - where the business constraint is correctness over TTM, for example. If not though, it can be a company killer. You can end up shackled by your domain models, and small updates have massive cascading consequences.

I've seen developer's entire sprints consumed by tasks that are abstraction related, and don't provide business value. I've personally known several developers that have told me directly that they don't like shipping software, they just prefer to play with frameworks and development theories. While those are extreme cases, I know many more developers that fall somewhere around there. I'm not sure why, but I think Typescript encourages this soft of thing. I get a sense that the whole ecosystem is more about the software process than delivering valuable features to the users. Though those things aren't mutually exclusive, when taken to excess I've seen software process and tooling devolve into a weird sort of navel gazing that's a barrier to delivery.

------------

#4 Longevity

------------

I prefer to stick to standards. I also tend to avoid frameworks, I use Web Components as a component solution, and keep everything as vanilla as possible. I don't mind using stable libraries, like date-fns or lit-html, but I've been burned too many times by multimillion dollar boondoggles that result from framework churn.

I encourage my team to pick technologies and development methodologies that have a five year lifespan as a minimum goal. I have code I've developed in javascript that's been running in production for 15 years without needing a major overhaul, and with stable dependencies.

On the other hand, I've had TypeScript codebases that completely broke based on rule changes that came from a TS update, and required significant revamping within six months of being authored.

While I do think that TS can be beneficial for some projects and teams - specifically ones that require a high degree of formalism - most of the time I don't see it providing concrete business value. I see it consuming dev cycles for limited benefit.

I am looking forward to the optional typing that's currently a stage 1 proposal. I miss AS3, which I thought struck the perfect balance between static and dynamic typing. Static by default, but it was easy to opt out when being dynamic made more sense.


I strongly agree with #1 and #2 and that is why I like typescript. It keeps things simple for me. I can look at what a function's inputs and outputs are without having to guess. I don't have to worry about having an array of strings and then someone deciding to throw a boolean in the middle. I know what all the keys on my object are and what kind of values they will contain. Code I have never looked at I can quickly figure out the structure.


I’m not getting into the pros and cons. All I know is that I dragged my feet for a few years and regret doing that. It’s been incredible. I now see javascript as a compile target.


I remember Flow being a little more strict. Typescript has much higher adoption now though so that has its own perks. Both are far and away superior to untyped JS.


Type checking and strongly typed languages are rapidly taking market share and in the near feature, except for niche specific software, mostly everything will be typed. There are a few reasons for this: it makes software easier to change and to test, and in a scenario of fast-growing complexity like the world we live in today, it is better suited for software development.

I would recommend to every software developer to learn the type ecosystem inside their language to make sure they have a good/high-paying job in the near future.

In 5 to 10 years, almost every serious engineering job will be working with an ecosystem that contains types.


It's got its advantages, but they had an opportunity to solve one of JS's biggest weaknesses—the terrible standard library. And they just... didn't.


Depending on your project, you may find that Dart+Flutter is a suitable alternative. The Dart syntax is simpler than Typescript, while meeting similar goals.


I can't believe they chose an array for the Tuple type. Which has no sensible equality definition as arrays in JS are references.


I generally think it is worth it. In React+Redux, Typescript enables a lot of help in the IDE and catches a few problems or bugs.


Learn infer and extends and you will accept all the downsides being zen from the height of your highly well typed codebase. If you don't find the following compelling:

  type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never;
  type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}`
    ? IsParameter<PartA> | FilteredParts<PartB>
    : IsParameter<Path>;
  type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : number;
  type RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key;
  type Params<Path> = {
    [Key in FilteredParts<Path> as RemovePrefixDots<Key>]: ParamValue<Key>;
  };
  type CallbackFn<Path> = (req: { params: Params<Path> }) => void;
  
  function get<Path extends string>(path: Path, callback: CallbackFn<Path>) {
    // TODO: implement
  }

  get(
    '/purchase/[shopid]/[itemid]/args/[...args]', 
    ({ params }) => {
      params.shopid // number
      params.itemid // number
      params.args // string[]
    },
  );
(https://lihautan.com/extract-parameters-type-from-string-lit...)

then you probably don't need TypeScript, or types in general. And that is fine.

As to the points:

(i) 99.99% of everything is being developed by someone else in our current stack, but here comes the benefits of open source: don't like how a project is going? fork it and maintain it yourself;

(ii) If you don't use a NPM package with the last release older than 2014 (and why would you given your (i)st fear), chances are pretty high (95%+) the library is written directly in TypeScript or there is a DefinitelyTyped package with the types;

(iii) Type errors, those that come directly from TypeScript, are pretty straightforward (was expecting X, you passed Y);

(iv) Yes, TypeScript should have never been written in an interpreted language, but what were the options in 2012: C? C++? Maybe some day in the unspecified future, we will have a Rust/compiled language implementation with microsecond transpilation time.


On the one hand, I like this very much.

On the other hand, if I open a project and I see many lines of complex types that don't do anything and I have to understand these types to use them to fix some bug, I'm going to say words out loud that I cannot write here.

I've seen projects where there were many lines of complex types and, after updating some dependencies, there were many type errors even though the project ran fine and the tests were all green. Pisses me off every time.

So in the end, I rather just see `params` be `unknown` and create a function to extract typed values, like `getNumberParam(params, 'shopid')` that returns a number or throws some kind of error. That way, you can compile-time checks AND run-time checks.


As always, it's a problem of balancing complexity vs. utility while striving to raise the level of abstraction.

With regards to TypeScript, any, unknown, never are perfectly valid types and plenty useful, just need to be used appropriately.


Did you write that blog post? Cripes, it is amazing. What a brilliant idea. Thank you to share. My brain is wired for C++ templates, and the technique makes good sense!

To your last point: Why not C#? It is interesting did not mention it, as TypeScript came from Microsoft R&D (as I understand).


I did not write the blog post, it was just a simple infer/extends non-trivial example explained in depth, commonly used in packages like express and so forth. TDungeon [1], a game running on the TypeScript type system, really showcases how powerful the type system truly is.

Why not C#? Probably because Anders Hejlsberg [2], lead architect of C# and core developer of TypeScript, wanted something different. More of a sociological, rather than technological, reason.

[1] https://github.com/cassiozen/TDungeon

[2] https://en.wikipedia.org/wiki/Anders_Hejlsberg


    I want to skip over the static typing benefits argument, because I think it
    is well understood that static typing is a good thing and if we could bless
    JavaScript with a built-in and robust typing system then I don't think many
    people would be against that.
Well, yes. That's what Typescript is. If a built-in and robust typing system were added to Javascript, it would be the same thing as integrating Typescript into the ECMA spec. for Javascript.

EDIT (some more thoughts):

    For example, a new package you install can require a new TypesScript
    version. Once installed, you then may need to update your source code. This
    can place quite a high tax on the developer, where perhaps a 10 minute
    change becomes hours long.
Yes, that's not very different than upgrading to a new version of e.g. Python or Ruby on the back end. The problem is that you're seeing Typescript as "just a framework", rather than a compiler/interpreter. If you view upgrading Typescript versions the same as e.g. upgrading Python or Ruby versions, and plan for it accordingly, then you'll at least have the correct expectations regarding the scope of work, even if the actual work to do isn't any less.

    Most libraries do not document their types, or have no examples using
    TypeScript.
If a type system were integrated into Javascript itself, it would have to be optional, in order to maintain backwards compatibility with the vast untold billions of lines of Javascript that are out there. Thus, you'd have exactly the same problem. It's very difficult to add a typesystem to a language after the fact.

    Errors are long and don't provide enough detail. They will explain a type
    mismatch referencing many types you may not have ever seen, and are not
    documented anywhere. Except for simple errors, many of them are very hard to
    follow to a remedy.
Poor error messages are an issue with any type system that allows generics. Typescript's error messages are, at least in my experience, better than C++'s error messages. I find this remarkable, given that C++ was designed as a typed language from the beginning, and Typescript has, as one of its design constraints, strict backwards compatibility with Javascript.

    I referred to TypeScript as a framework which it isn't. However it feels
    similar to me in that you are at the whim of TypeScript developers and how
    they decide to progress with the language.
That's true of any programming language, Javascript included. If you're writing Java, you're at the whim of Oracle. If you're writing C#, you're at the whim of Microsoft. If you're writing C++, you're at the whim of the C++ standards committee. If you're writing Python, you're at the whim of the Python Steering Council (and you used to be at the whim of Guido Van Rossum). Every programming language has some person or committee that's in charge of it, and if you're choosing to use that language, you're implicitly accepting the decisions made by that person or committee.


v) It’s been well over a year, and IntelliJ Idea still requires me to go to the settings page to enable an experimental feature to be able to run a simple helloworld.ts.

Not sure whose domain this falls in, but the situation is a coal mine canary that tells me the whole ecosystem is not up to the level I want from my production tools


Since the front-end world was upended by webpack and react, my favourite change that I would abandon last is typescript


i agree, I have to work with typescript for my current job and I hate every second of it. I was never a fan of any languages that require transpiling. the trade off and trouble it comes with is not worth it for the small benefits. Im not a fan of JS in the first place but typescript just makes it worse.


TS can't solve any real problem, so skip it. Dart & Flutter worth it if you need cross-platform GUI.


Flutter web isn't that great. Even scrolling is a fundamental issue with it which is never going to be fast using their current approach.


Compared to javascript, yes. Compared to any other simpler statically-typed language, no.


Well, I like Reason better. The type system is more robust and to infers more type.


I love JS, but I want types. I don't want TypeScript though, but I'll do it if the job requires it.

Has anyone tried building in flow for a large project? This was facebook's static type checking approach: https://flow.org/


TypeScript itself is good but typescript errors are bad and annoying


typescript as a language on it's own, is worth it, however the nightmare of the landscape of all the poorly develop libraries and endless layers around it causes me to never pick it for a backend project.


I prefer to avoid TS. I can’t stand its type system without pattern matching


Yes, in all cases except proof of concepts only demoed once. And even then probably still.

i) You can wait years to update TypeScript itself. I've never run into incompatibilities before.

ii) That's the libraries' fault. Without types, you can pass in total garbage and it doesn't work. With types you can only pass in some garbage and it doesn't work. All the Javascript examples work in TypeScript except now you will be warned that your code won't work before you try to find edge cases to test.

I've had the pleasure to use Frida a while back. It allows you to instrument running native applications using hooks written in various languages, though the live debugger usually uses Javascript. The documentation of many functions is scarce, to say it nicely. Without the TypeScript bindings, I would've never gotten most of these functions to work. You can find example code online but half the time that example code will be buggy and not do what it appears to do exactly because there is no type check on the plain JS API.

iii) I disagree, they're verbose but not that difficult to read. "You specified this but the type doesn't exist" or "you didn't specify this thing the type needs" is almost always the problem, it's just a little over eager to tell you where you're missing something.

iv) Okay this is definitely a downside. If you're not using Babel or another transpiler/minifier/obfuscator already, you'll add an extra build step. A minor one, in my opinion, but a build step nonetheless.

In my experience, TypeScript isn't making progress slow. It's making you fix your bugs and broken promises before the customer calls that your code doesn't work anymore. If you're passing strings instead of numbers you're going to break your code eventually, only now you'll have to get your code to working order beforehand.

Working on a codebase that's a few years old and added typescript retroactively, my experience is that renaming JS files to TS will instantly show you three to five bugs in every single JS file you come across. Import errors all throughout the code base, because it turns out components got reused wrong and what seemed like an optional label that didn't have any contents was actually broken for five years.

TypeScript gets even better with a nice and strict set of linter rules. Not just the builtin ones, also extra stuff like "don't use any everywhere to avoid typing things" and "specify what you're returning when you're returning something". With the stricter guarantees the language can deliver because of types, the code quality analysis can be a lot better as well!


Why are we still talking about this.


Worth it if JS is worth it.


Have you tried Deno?


Yes


The TS type system is incredibly powerful, and I wish I could apply to other languages out there. The biggest annoyances with it come from the fact that it isn't its own language; you get runtime errors due to incorrect or out-of-date types (often maintained by people other than the library authors). Also, "any" and "unknown" types tend to sneak in via default generic arguments, vague external module typedefs, etc. These types can spread through your codebase, preventing the type checker from doing its job, and the "strict" mode doesn't do much about it!

Generally speaking, I have to be extremely careful with working on a JS/TS project. I use the strictest modes possible and enable as much linting as possible. I also use the type-coverage module and fail the build if the `any` type gets applied anywhere.

As another general complaint, NPM doesn't do enough to incentivize its users to release quality software. JS/TS has always been very trend-based and social, and even just running a few simple lints and prominently displaying a score on NPM would probably really help the community improve its standards.

Take pub.dev (Dart), for example. Here's a module page: https://pub.dev/packages/firebase_core. The score is displayed prominently, and if you click on it you get a full breakdown of how it was calculated: static analysis, up-to-date dependencies, and documentation (although the coverage is not 100% for this module, so I think it's wrong to assign full points). When you upload to pub.dev, you want a score of 100! It doesn't guarantee that the module is fantastic software, but at least the basics have been taken care of.

In my opinion, the most important piece missing from the score on pub.dev is test coverage. Take for example a page from Metacpan (Perl packages). Here's a module I've released: https://metacpan.org/pod/Algorithm::AM. On the left you see displayed the automated test results, including the test coverage, which has been submitted by volunteers who downloaded and tested the code on a variety of platforms and Perl versions. There's also link to a "kwalitee" page, which is similar to the pub.dev score (though this could be much improved by having an actual score and displaying it prominently on the main module page).

Now an NPM module: https://www.npmjs.com/package/react. What info do we have about the quality of the package? Essentially just the activity from the community (open PR's and issues, downloads). We have no idea how well it's tested, what kind of static checks have been performed, whether your editor will be able to display documentation or typing when you mouse over a method from the library, etc. (TypeScript is mainstream enough now that it should be fine for NPM to provide a bit of special handling for it.) Most 3rd party libraries are from individual authors and probably have very little activity. When deciding whether or not to use them, right now you need to dive through the code to check if the basics are taken care of. Having some of this automated would save a lot of time.


Having spent the last two years back in JavaScript, and in the process of moving a >10y project to TS as a part of a larger refactor, emphatically yes it’s been worth it. I have been hanging on to tsserver to bridge the gap for two years, and well… it’s night and day.

I can add ~95% of the same safeguards without it, but I’ll spend a lot more time doing so and it’s a lot harder to get buy in to make them stricter than my own editor.

> For example, a new package you install can require a new TypesScript version. Once installed, you then may need to update your source code. This can place quite a high tax on the developer, where perhaps a 10 minute change becomes hours long.

If your project is already strict and if you generally have a good sense of the areas TS doesn’t cover, you probably wouldn’t need to update anything for the last couple years. If your project isn’t strict, you’re probably benefitting from updates more closely matching the semantics you wanted in the first place.

> Most libraries do not document their types, or have no examples using TypeScript. Some worst offenders: Apollo, Protobufjs. The type definitions exported by these libraries can be large and complex, and the error messages emitted by TypeScript are so long and cryptic the result is often a drawn out process of trial and error along with trawling through source files.

It’s fairly trivial to add local type defs if you’re at all interested in the type safety it brings. They’re almost universally easy to transfer to PRs for DefinitelyTyped (which admittedly I should do more often, and I should open a few after I land this work in my project).

> Errors are long and don't provide enough detail. They will explain a type mismatch referencing many types you may not have ever seen, and are not documented anywhere. Except for simple errors, many of them are very hard to follow to a remedy.

This is true. You’re right. If you want a little helpful pointer:

  type Debug<T> = [AnyType<T>] extends [never]
    ? 'My understanding of AnyType failing'
    : AnyType<T>
Edit: this ^ was typed on my phone from recall and I’m tired and might not be quite right. I’m happy to revise it tomorrow if that’s the case.

It’s not great but it’s basically a very slow way to walk up the type resolution stack until you find what doesn’t behave the way you expect.

> Transpilation takes time, and always adds a burden to developers. I didn't mind so much with ES6 etc because eventually many functions were included in a broad set of browsers. There doesn't seem to be much progress including TypeScript in a browser, and feels like these complicated transpilation steps could be with us for a long time.

ESBuild, Vite, SWC and such have basically made the build step instantaneous. They’re not without config woes, but they’re worlds better than what came before. So much so I will volunteer to help you set up a project’s build if you do the very easy legwork to find any number of ways to contact me.


Yes


Yes.


I make it about 20 minutes into a JS project before I have to go install TS because I'm losing my mind. It's such a no-brainer that the question barely parses. Javascript is medieval and typescript is... less so.

I know it's not an interesting answer and a lot of other people say the same thing; guess I'm just casting my vote.


There was a time, once, when I did things with vanilla JavaScript. Not huge, ambitious things, but not trivial things either. Now TypeScript has ruined me. I'm pretty sure it didn't really mean to, but I've become so used to encountering `any` and saying "that needs to not be" and fixing it that now there's a reflex in my head that makes the thought of `any` just uncomfortable. I try to write vanilla and I start sweating, it just feels so unsafe.


You couldn’t pay me to work with Vanilla JS on any real life project. It feels like going back to horse and buggy.

The biggest things I wouldn’t be able to live without:

- the self-documenting nature of Typescript code (I instantly know what a function accepts and returns by hovering over it).

- the comprehensive auto complete my ide gets (saves hundreds of trips to the docs / source code per day).

- the incredible productivity gains when refactoring (change one thing, instantly get notified of all 30 places in the codebase that change introduced errors and clean them up in minutes).


I haven't worked on a Ts project, but feels like i already get most of the stuff you mentioned, through ts-check in a regular js project.


> on any real life project

Could you elaborate on what the barometer/measuring stick for what makes a project real life?

I think I know what you mean. Bigger than ____ lines of code/files I'm guessing?

X number of classes/interfaces/APIs?


Sorry, “real life project” was a poor metric. I suppose I meant anything where bugs would have a negative impact on the world — either a business or individual. Realistically though, anything that I’m expected to spend more than 20 minutes working on. I’m quite the extremist when it comes to languages and highly opinionated in general.

I compulsively rewrite JS into TS and 100% of the repos I work on have “allow-js” set to false in the tsconfig. It seems to be fueled by the same “OCD” I get when designing UI, organizing css, or making music for example.


Not GP but I would never use bare JS again for anything other than maybe like a 20 line script, for the same reasons as GP


Not the parent poster, but… the size of the codebase is for sure a criterion, but also code I have to continuously maintain or add to, or code written by a team where I have to read others’ code and vice versa.


Important distinction:

Are types worth it? Yes. Is typescript worth it? Maybe.


[flagged]


Agreed. TypeScript is the art of making JavaScript into Java.

Never bet against JavaScript.


Can't tell if this is serious or not.


It's lipstick on a pig, and yet another layer of complexity on top of the myriad of modern web development.

The solution to better web development is staying as far away from JavaScript as possible, not polishing what is frankly a turd.

I think it's masochism to have a Javascript project that big that benefits from strict typing.


The whole shtick (and beauty) of Javascript is that it is a dynamic language. In some point in time corporate Java people started using JS, and now we have this : "is well understood that static typing is a good thing". It's not. But as always you have a vocal minority, influencers and evangelists shouting their BS, about how TypeScript has terraformed theirs lives and they can't imagine life without it.

Use your head, if you don't like TS, don't use it.


I'd argue that the shtick of javascript is that it runs in a browser. The dynamic thing seems like more of a coincidence to me.


Id argue the static typing is great, and the best part of Java that is otherwise ruined by OOP. Give me the types and leave out all the OOP factory garbage, and you are left with the best parts. That’s what typescript ends up being.


Typescript is significantly better than java imo, in that it can figure out what the right object shape is on its own for the most part, rather than needing to write another file for every intermediate data object in a process flow


This post is a joke right? The world has moved on. JS *is* the target, but it is *no longer* the source.

There is so much more to software development than the how quickly one can vomit code into their editor of choice. If typescript is slowing you down, your code is *bad*. End of story.

Continually pretending that types don’t matter is laughable. The thousands of dynamic language projects with littered with type-hints, type-assertions, and type-verifying unit tests proves otherwise.


Good code takes a lot of thought and care, and won't materialize just because you use static typing.

So why am I spending so much time applying static typing instead of thinking about how the code should flow, about what's the best abstraction, writing thorough documentation.

Typescript comes at a much higher cost than built in static typing, and I don't think it's worth the investment.


I don't think you actually read OPs post. They were actually pro-types, but didn't like the overhead that comes with TypeScript.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: