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.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: