6 ms·
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
by DanRosenwasser 4y ago
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>.
- roberttod 4y agoThanks 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#typescript 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.
- lstamour 4y agoRe 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 https://github.com/stephenh/ts-proto has 4.7 support listed in its readme.
- throwaway2037 4y agoThis is a very interesting idea!
- roberttod 4y agoWe 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.
- aozgaa 4y ago> 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.
- norman784 4y ago> 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.
- dclowd9901 4y agoGreat 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.
- 8n4vidtmkvmk 4y agoTS#### error messages was a brilliant idea to make them more ~googleable~ bingable at least.
- ygra 4y agoIsn'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.
- arethuza 4y agoI guess TypeScript and C# having Anders Hejlsberg in common probably helps with things like that?
- ericmcer 4y agoThanks 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.
- benfrl01 4y ago> 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.
- markeibes 4y agoWhat's Math.sqrt("hello")?
- BigJono 4y ago[flagged]
- HideousKojima 4y agoSo 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.
- o_m 4y agoI 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?
- kbendyk 4y ago(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.
- jemmyw 4y agoIf 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!
- ryanwheale 4y ago> 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
- jemmyw 4y agoI 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.