7 ms·
Always when typescript is is compared with js, people talk about you get less bugs in typescript. I am honestly curious to see some evidence. In my opinion appl
by holoduke 6y ago
Always when typescript is
is compared with js, people talk about you get less bugs in typescript. I am honestly curious to see some evidence.
In my opinion application bugs are usually in the flow itself and have nothing to do with wrong types. I work a lot with both plain and Typescript projects. I used to like Typescript. But not anymore. With typescript applications tend to become bigger and more complex. Most devs using it have never seen vanilla js and are more java minded that prototype minded.
IDE code completion works better for typescript. For sure. But is that really essential? Sounds a bit like the typical Java developer who works with giant spring applications containing classes with hundreds of methods spread in many files in a 10 layer deep folder structure.
- timdaub 6y agoAs someone that's extensively testing their application, I don't get the bug argument either. Sure some bugs are found during compile time. Actually, it's not bugs the compiler finds. Rather it's inconsitencies between types and the rest of the code. But when testing properly, these should anyways be found later. Or am I missing something?
- egeozcan 6y agoIt's a given that you can reduce the number of bugs in your app eventually, with any method/tool you can imagine, given enough time. That'd be still true if you were designing using sticks and stones on sand. Why not use another tool that helps you fix bugs easier, faster and sometimes spare you from writing them at all?
- timdaub 6y agoWhy so aggressive? I asked a simple question out of interest. Again, I think there's a difference between bug and a coding error. A bug is a mismatch between a software's function and the user's expectation. And a typed-inferred error during compile time is just a hint that some code is incorrect. It may lead to a bug, but at the point of compilation, it's not a bug.
- egeozcan 6y agooh I didn't realize I sounded aggressive, sorry if it came off that way, cheers! I'd like to point out that if you agree that typescript prevents stuff that may lead to bugs, without getting into the semantics of what a bug is, you may agree that it's useful.
- Jestar342 6y agoInconsistencies between types and rest of code _is_ bugs. I'm willing to bet my house that "TypeError: object doesn't support property or method" is the #1 bug in JavaScript's sphere.
- timdaub 6y ago100% agreed. But my point is that I usually find these types of bugs really easy when unit testing.
- KronisLV 6y agoThe assumption here is that there are unit tests that cover the areas containing these sorts of bugs. It can prove to be false because many projects don't have sufficiently good code coverage. Of course, it's also possible that there simply are no unit tests at all. In those circumstances, TypeScript might just result in less bugs overall. While one could argue that unit testing should be commonplace, reality doesn't always live up to that standard.
- kungito 6y agoReal unit tests (not integration tests) are poor man's types. Usually when you have very small unit tests asserting inputs and outputs of methods you would simply assert those with types in more powerful languages
- hajile 6y agoHaskell has pure functions everywhere and a much stronger typing system than TS, but unit testing is still considered important. Someone else will be changing that code later. Knowing (for example) that the parameter is a string will be zero help in knowing what is being done with that string. It also won't help know what edge cases the code was handling. Also, types give a false sense of security. A new project was integrated into an old website (one with legacy dependencies, but doing millions in transactions every day, so unchangeable). It broke and they couldn't figure out why. They had the TS types for functions, but an old framework (prototype or moo iirc) overrode js built-ins with incompatible versions. Later they got bitten again when that code changed the object types. If they'd been writing js, they would have written dynamic checks from the start, but it's easy to forget that once you compile, it's just js.
- egeozcan 6y ago> But is that really essential? Sounds a bit like the typical Java developer who works with giant spring applications containing classes with hundreds of methods spread in many files in a 10 layer deep folder structure. It's not only your stereotypical Java developer who has to maintain large code-bases. There are much more monolithic code-bases than there are micro-services. Also, probably you have a much better memory than me, but I, like many others have trouble working with random objects with no contracts. Additionally, try using a library like io-ts and you also get validation against types. Typescript made me love JavaScript again.
- submain 6y agoBug reduction estimates range from 15% [1] to 38% [2]. One can also argue it greatly improves refactoring speed. 1: http://earlbarr.com/publications/typestudy.pdf http://earlbarr.com/publications/typestudy.pdf 2: https://www.reddit.com/r/typescript/comments/aofcik/38_of_bugs_at_airbnb_could_have_been_prevented_by/ https://www.reddit.com/r/typescript/comments/aofcik/38_of_bu...
- mekster 6y agoTypescript already stops bugs right when I'm typing, so it helps before compile or run time. Also, reliable auto completion is very helpful not just for the method names but for properties etc.
- Vinnl 6y ago> bugs are usually in the flow itself and have nothing to do with wrong types I'm not sure what you mean by "in the flow itself" exactly, but just yesterday a teammate of mine was using one of our libraries in a small project without TS. They first called getThing(), which might return null, and then passed the result to doSomethingWithThing(), which did not expect a null. That sounds like a "flow" problem to me, and TypeScript literally would've warned them of it. (Since this particular combination of functions is likely to be common, we added a runtime check for people who aren't using TypeScript now.) > Most devs using it have never seen vanilla js and are more java minded that prototype minded. I think you might be underestimating the number of people who strongly dislike Java's type system but very much appreciate TypeScript. They're very different, and hence it's very much possible to like the latter for reasons that do not apply to the former, or to dislike the former for reasons that do not apply to the latter.
- CraigJPerry 6y ago>> They first called getThing(), which might return null, and then passed the result to doSomethingWithThing(), which did not expect a null When i think of a flow issue it's more things like "i forgot to check if the user was authorised to perform doSoemthingWithThing()"
- mlnj 6y agoAnd with TypeScript I get notified that I forgot something and it shows me exactly where.
- CraigJPerry 6y agoCan types solve that problem? ... // if(isAuthorised(user)) { doSomethingWithThing(thing); // } ... How would typing detect the missing authorisation check in the program flow? Surely this is a case where testing is the correct tool to use?
- deleted 6y ago[deleted]
- smoe 6y agoI have worked with Javascript for frontend quite extensively since 2005 and with Typescript since about half a year. In the general case, I don't have strong opinions about strong vs dynamic typing, or getting error during compile- or runtime. But my gripe with Javascript has always been, that you often don't get any direct errors at all but instead end up with unexpected values in a different place that you then have to tediously backtrack. A contrived example to illustrate what I'm referring to: some_obj = {day: 2, ...} next_day = some_obj.daz + 1 // typo in attribute gives you `undefined`, adding 1 to it results in `NaN`, not a number. date = Date(2020, 11, next_day) // returns a`Invalid Date` object console.log('date: '+ date) // outputs "date: Invalid Date" In Python, every line after the first would raise a runtime exception and is thus in my opinion much easier to debug. What I particularly like about Typescript is that I can use as much or as little of it as I deem necessary. E.g. I start off a prototype using the `any` type a lot, and only in future iterations, I start tightening the definitions as the requirements for the project become clearer. So far the overhead has been quite minimal. The one downside so far is, since I learned Typescript by just starting using it, without a deep dive in documentation, books, etc. trying to grok code, well especially type definitions of libraries (which I often prefer over reading documentation) that use the more advanced features has been quite a challenge.
- matt_kantor 6y ago> The one downside so far is, since I learned Typescript by just starting using it, ... trying to grok code ... that use the more advanced features has been quite a challenge. I'd suggest skimming this page (a concise overview of the advanced features): https://www.typescriptlang.org/docs/handbook/advanced-types.html https://www.typescriptlang.org/docs/handbook/advanced-types....
- kilburn 6y ago> What I particularly like about Typescript is that I can use as much or as little of it as I deem necessary. E.g. I start off a prototype using the `any` type a lot, and only in future iterations, I start tightening the definitions as the requirements for the project become clearer. So far the overhead has been quite minimal. I started working this way and it was fine, that's how I always worked anyway. Then I started leaning towards working the types first and the code later, and I've found it works better and better for me. Much of today's programming is "stitching pieces together": pieces from the libraries you are using, from external services you use, from your platform's APIs, and then creating the few extra pieces that are unique to your puzzle. When you code first, you are directly painting pieces while trying to picture how the final puzzle will look like in your head. When you type first, you are just cutting the shapes of the missing pieces and already assembling the puzzle. Once this is done, you are left with a full picture that has some blank spots, and it becomes much easier to just paint those in.
- cryptica 6y agoI share this point of view. For the last few years, this perfectly reasonable and balanced viewpoint was taboo so it's good to see more and more people approaching the debate rationally as opposed to waging a religious war over gut feelings. Personally, I have no issue with TypeScript purely as a language and I concede that it provides much better IDE code completion than JavaScript. That said, I don't agree that its benefits offset the drawbacks of the transpilation step, the source mapping and the added versioning complexity between JS and TS. I also miss the way that JavaScript encouraged people to define very simple function signatures (e.g. strings, numbers, plain objects/clones as arguments and return values). For example, I really liked how the React/Redux community came up with a philosophy around cloning state objects before returning them from functions in order to prevent unexpected mutations later (essentially force everything to be pass-by-value). I think this philosophy does not translate very well to TypeScript which encourages developers to pass around complex live instances (which have their own methods) instead of raw objects and other primitive state representations. As Alan Kay pointed out, OOP is not primarily about objects, "The big idea is messaging". Instances should communicate with each other via simple insterfaces using simple messages; they should avoid passing complex live instances to each other. If an instance has methods, that is a complex live instance and it shouldn't be used for messaging between different components.
- acemarke 6y agoI maintain Redux, and I can confirm that TS does _not_ "encourage devs to pass around complex live instances" any more than normal JS does. You can do FP and immutable updates in TS, just like you can do any other code. See our "usage with TS" docs pages for examples: - https://redux.js.org/recipes/usage-with-typescript https://redux.js.org/recipes/usage-with-typescript - https://react-redux.js.org/using-react-redux/static-typing https://react-redux.js.org/using-react-redux/static-typing - https://redux-toolkit.js.org/usage/usage-with-typescript https://redux-toolkit.js.org/usage/usage-with-typescript
- cryptica 6y agoWhat you're claiming here does not match the evidence from your links. For example, in your second link, one of the functions expects a 'complex' instance DispatchProps which has a method toggleOn... This abstraction doesn't make sense conceptually. What is a DispatchProps? It doesn't adhere to Alan Kay's notion of a 'message', it's clearly a structure (it's a complex one because it exposes a method). Components should communicate to each other via messages, not structures. Also, the method builder.addMatcher(...) accepts a function as an argument - It doesn't seem like an ideal abstraction either. Functions are not messages. Also, the thunkSendMessage function signature is very complex; the return type is highly convoluted. That's definitely not a message. Overall, I see a lot more of these complex instances being passed around in these examples than used to be the case with JS when mostly just raw objects were being passed as arguments and returned. You can already see the complexity seeping into the interfaces. Just a few years of TypeScript is distorting the original philosophy. I remember Dan Abramov was very careful about what to pass into functions and what to return from them and made it a point to encourage cloning objects using the ... spread operator. That philosophy appears to have been forgotten.
- scotty79 6y agoMy personal expeirience with TS is that when I applief it to my JS code I always found additional bugs in it that I wasn't aware of. Some of the bugs exposed were the bugs in the 'flow'.