The last days of my type checker for JavaScript

(jsmonk.github.io)

74 points | by bk496 10 days ago

11 comments

  • madeofpalk 10 days ago
    For starters, I think the author should take this all as a resounding success. I'm sure they learned a lot - technical and othewise - from the project, and that's always worth it. I don't believe the only two options are massive viral hit or failure.

    But I don't think I agree with the authors conclusions that there's less interest in type safety or strict type checking. I suspect the author finds Typescript too leanient (there's plenty of ways to trigger Typescript's unsoundness) for their liking, but I do think there is an overall trend to use Typescript to design and build more reliable software.

  • begueradj 10 days ago
    It takes a lots of wisdom, humility and a pragmatic vision for a man to confess that an important enterprise he devised and worked on is not worth to continue investing on.

    Do not forget you learned a lot along the path. That's something no one can take away from you.

  • wccrawford 10 days ago
    There's something bittersweet about doing something well, and then eventually having something else take over from it. You had that feeling of doing it really well and being successful, but you don't need to keep pouring energy into it now and can work on other things with a clear head.
    • dmurray 10 days ago
      I don't think the author completely feels this way. He feels Typescript is the VHS to his Betamax: the approach that won out despite being technically inferior.

      > unfortunately, I see that nowadays, TypeScript won. The idea of strict type-checking for JavaScript is less popular than in 2019.

      > [Typescript's types] give people a fantastic tool to cover existed code with types but doesn’t force to re-design it to make it safer.

      • meandmycode 10 days ago
        By 2019, typescript was for some time dominant over flow and had won the js ecosystem, so either the author was naive to this or isn't quite portraying the story well.. I think it should be fine for the author to say they had personal preference over something like flow and so you developed tools to their own preference
        • thiht 10 days ago
          Yeah in 2019 Typescript was already the clear winner, no contest
  • pjc50 10 days ago
    I feel like in the longer term we'll eventually get, via WASM or otherwise, another language that we're allowed to use in the browser, which can be properly type-safe from the beginning.
    • couchand 10 days ago
      That time is now. I've been shipping Rust code to browsers for years...
      • berkes 10 days ago
        Rust is still the only language with decent tooling and an ecosystem to compile to WASM.

        Many other languages haven't passed the PoC stage. Several are ready, and doable (C#, Go?) but hardly as easy and common as with rust.

        At least that was the state when I looked six months ago. It's a fast moving area.

        So, yes, that time is now. But the only practical option is rust. Which may be enough, idk.

        • randomdata 10 days ago
          > Many other languages haven't passed the PoC stage.

          Wouldn't it be more accurate to say that WASM hasn't passed the PoC stage? There are quite a few languages that have great WASM support, to the extent WASM allows, but have to bring all kids of workarounds to deal with the shortcomings of WASM as it sits. An especially challenging problem as it relates to browser use with those workarounds is that they bloat the artifact size. Few are willing to subject users to multi-megabyte downloads.

          Work is being done on WASM to address those shortcomings, but hands are pretty much tied until that arrives. Until then, the "lower level" and heavily constrained languages will be left to stand alone.

        • pjc50 10 days ago
          C# Blazor certainly exists and works, although it feels really clunky. Only suitable for a true application, not for integrating with web pages. It's almost the inheritor of the Java "applet" and the HotJava browser.
      • marcosdumay 10 days ago
        Yeah, but Rust is not great for UI code full of global values.
    • papa0101 10 days ago
      That was google's original plan with Dart.
      • zogrodea 10 days ago
        I believe Dart was originally gradually typed, and then abandoned the gradual typing for strict-typing-by-default? That doesn't quite sound properly type-safe to me although still safer than how Javascript is by default.

        My only reference is a memory of this talk by Richard Feldman but I might be wrong or misremembering. https://www.youtube.com/watch?v=Tml94je2edk

        • igouy 10 days ago
          Released 22 February 2018

          Dart 2.0 implemented a new sound type system

          Dart's type system, like the type systems in Java and C#, is sound.

          https://dart.dev/language/type-system

          • zogrodea 9 days ago
            Thanks for the link. I'm aware Dart currently has static typing similar to Java and C#, and has had it for some time,

            My question was different though and I was asking (quoting comments further up the chain) whether "google's original plan with Dart" really was to allow for a programming language "which can be properly type-safe from the beginning".

            It seems that claim about the original intent is false. I checked Wikipedia [0] which states "Dart 2.0 was released in August 2018 with language changes including a type system" and the reference they link seems to corroborate that, before 2.0, Dart didn't have a sound type system.

            Thanks for prompting me to dig deeper (I probably wouldn't have done it without seeing your comment).

            [0] Quote found under the history section. https://en.m.wikipedia.org/wiki/Dart_(programming_language)

            • igouy 7 days ago
              Thanks, I was probably responding to “That doesn't quite sound properly type-safe to me” in isolation.
      • Yoric 10 days ago
        Is Dart sound these days? When I tried it, it was pretty easy to trigger type errors at runtime.
        • igouy 10 days ago
          These days Dart — considers all variables non-nullable — enforces sound null safety."

          https://dart.dev/null-safety

          • Yoric 7 days ago
            Well, null safety is a good start.

            But I seem to remember that the type-checker got confused rather easily with nested closures, for instance, or co/contra-variance.

    • wk_end 10 days ago
      Consider using Reason and/or Rescript. Ocaml with a nice syntax and clean JS interop.
  • Waterluvian 10 days ago
    > The idea of strict type-checking for JavaScript is less popular than in 2019.

    I’d be shocked to find this to be true. Back then I’d always wonder, “are there typings for this library?” Now I don’t have to.

    • __s 10 days ago
      By that I think he meant to differentiate Hegel from TypeScript as Hegel being strict, as opposed to TypeScript being what is often described as gradually typed
    • nevon 10 days ago
      The keyword being "strict". Typescript is more popular than ever, but soundness is not a design goal.
  • joshstrange 10 days ago
    Here is another tool in the same vein that people might find interesting: https://gitlab.com/dejawu/ectype
  • qbane 10 days ago
    This project, along with TernJS, really inspired me to dig into the wild world of type inferencing of JavaScript with minimal annotation. TypeScript, or even JS with JSDoc comes with learning overhead. Pure JavaScript projects often cannot be easily typed in TypeScript's way without major refactoring, and sometimes a lightweight editor plugin suffices to provide enough insight for ease of development. There is no one-size-fit-all solution, and I wonder how far can something like context-aware autocompletion can go without TypeScript.
    • wyriwyg 10 days ago
      IMHO type checking for dynamically typed languages should be done by the IDE instead of messing up the language itself. Fortunately at some point there will be an addon for your favorite IDE that does the type checking without touching your code. Microsoft could have developed such a rigorous type check addon for VSCode, but (unfortunately) instead they went for Typescript, no clue why they preferred to do the latter, maybe another throw to dominate the no1 browser language?
      • qbane 10 days ago
        JavaScript is inherently untyped. Either the programmer tries to be very careful to make it type safe, or someone invents a programming language that can only compile to a sound subset of it. TS heads for the latter way. But things quickly go out of control when you introduce dependencies, and even a dependency without interface file can pollute your codebase with "any". I do not think TS would be mainstream if there were not many packages on npm that had included a type definition. On the other hand, a type checker/inferencer that "does less things" like Jedi has proved great success in Python community.
      • pjc50 10 days ago
        I don't understand this point of view: types are part of the code? Perhaps one could eliminate 90% of the need to write them down with aggressive use of Hindley-Milner, but in many places they're a deliberate choice.
        • randomdata 10 days ago
          The discussion taking place is about type checking plain Javascript. The comment you replied to questions why Microsoft didn't go down that road, something they ended up doing eventually anyway, instead of introducing a new language.
  • philipwhiuk 10 days ago
    > I see other opportunities to increase the language diversity on the web (further in the article)

    I'm unconvinced this would be a good thing.

  • gr__or 10 days ago
    Thanks for your hard work on making JS safer. You were working on exactly what I am missing most, sane error-handling. I hope TS picks up where you left off at some point.

    I was also happy to see the shout-out to Ben's Ezno. I'd recommend people start sponsoring that kind of work, it has the potential to make our JS life much saner.

  • noelwelsh 10 days ago
    Good post. It's important to realize when a project isn't worthwhile continuing. It's also important to realize that so-called technical criteria are only one dimension along which usage decisions are made. Technically inferior technology often wins out for other reasons (e.g. Windows vs OS/2 etc.)
  • smackeyacky 10 days ago
    I have been working with node for a couple of years now, not my choice but it isn’t tragic. This team uses TypeScript,

    I honestly don’t get the problem TypeScript is trying to solve. JavaScript has lots of wacky problems but its main advantage to me was the loosy goosy approach to types. I was a smalltalk programmer back in the 1990s and it felt pretty comfortable if very primitive in the way of tools.

    Typescript just seems unnecessary. Not sure why nobody built something like reentrent exceptions or cool stuff like that, instead they built a stupid jail that down compiles to unreadable sludge.

    Now I find out there were competing jails. What a strange ecosystem.

    • lucianbr 10 days ago
      How large are the projects you worked on? Usually type safety is more useful and appreciated in large projects, where strict interfaces between modules are more valuable. In small projects, the advantage is for the loosy-goosy, because you can move faster and anyway you have the whole thing in your head, or most of it.

      There is a lot of text written and voice recorded over what type safety is good for. It's reasonable to disagree, but to "honestly don't get" what the point of it is seems kinda strange. Like you haven't really looked into it.

      • mhh__ 10 days ago
        I think the point isn't really about the value of type safety but rather the value-add of bothering with the whole of typescript (as in the type safety they provide rather than an abstract ideal) versus some other solution.

        It's quite annoying IMO. Some of the things it can be infer are reasonably impressive but then that gets balanced out with having to write out a lot of crap that something a bit more HM-like would be able to nail immediately (rather than just "Any!? Fuck you").

        That and the refusal to add other value-adds (despite being a compiler in all but name) hobbles the union types and so on.

        • throwaway11460 10 days ago
          Could you give me some examples of this unnecessary code? Are you using type inference to its full capabilities? It's only really necessary to declare types at interfaces (function arguments, etc)... Is that what you're referring to?
      • igouy 10 days ago
        "Type safety is the property that no primitive operation ever applies to values of the wrong type."

        Smalltalk is type safe & not statically checked.

        page 263 "Programming Languages: Application and Interpretation"

        [pdf] https://cs.brown.edu/~sk/Publications/Books/ProgLangs/2007-0...

      • ReflectedImage 10 days ago
        It's not really true that type safety is useful for large projects.

        It's generally better to do proper micro-services.

        Type safety is the inferior way of doing it where you get hit with a double whammy of long compile times and extreme code verbosity.

        • zogrodea 10 days ago
          Network API contracts/documentation are just an attempt of type safety over the untyped network boundary.

          Network communications are the most tedious and annoying part of programming for me because of the validation of the request body and checking that it has all the fields needed.

          Microservices only increase the amount of documentation needed. I would prefer to lessen the amount of documentation by letting the compiler/code do the work instead.

          • ReflectedImage 9 days ago
            No, it's forced modularity. It's saying there are hard lines between parts of your program that can't be crossed. This prevents the over time formation of spaghetti code.

            It's like British tanks in WW2, your system is composed out of standard parts. Not necessary the best, but standard parts and that's what tends to be important.

    • madeofpalk 10 days ago
      Maybe I'm just not as good of a developer as you, but I often fail to understand 100% of the codebase, or I even make mistakes sometimes. Having a system catch my back to tell me what else I need to update in my refactor is a huge help for me. Maybe that's just not a problem those 10x developers have?

      > instead they built a stupid jail that down compiles to unreadable sludge

      Does it? The Typescript compiler mostly just erases types, leaving the code otherwise the same. Here's a non-trival example https://tsplay.dev/mA078N, where the output is basically the same as the input, just with type syntax erased.

      IIRC the only 'language feature' that Typescript actually compiles is enums, which is a bit of a big blob. There's compiler flags to 'fix' that, or you can just not use enums.

    • pjc50 10 days ago
      > I was a smalltalk programmer back in the 1990s

      Smalltalk (and languages in the same academic orbit, like LISP derivatives) seems to be a tool that fits a few people's hands very well, but there are no large smalltalk projects for two reasons:

      - that doesn't actually suit most people, so it's harder to find developers

      - the language maps well to one (1) human brain that keeps a model of what's happening, but that breaks down when larger teams of developers are involved.

      I guess that keeps the "small" in smalltalk.

      • igouy 10 days ago
        How do you know whether or not "there are no large smalltalk projects" (whether or not there have been large Smalltalk projects)?

        Seems like we need do no more than assert: Yes there are!

        ~

        But it's more interesting to look at how a real Smalltalk project worked:

        "A very large Smalltalk application was developed at Cargill to support the operation of grain elevators and the associated commodity trading activities. The Smalltalk client application has 385 windows and over 5,000 classes. About 2,000 classes in this application interacted with an early (circa 1993) data access framework. The framework dynamically performed a mapping of object attributes to data table columns.

        Analysis showed that although dynamic look up consumed 40% of the client execution time, it was unnecessary.

        A new data layer interface was developed that required the business class to provide the object attribute to column mapping in an explicitly coded method. Testing showed that this interface was orders of magnitude faster. The issue was how to change the 2,100 business class users of the data layer.

        A large application under development cannot freeze code while a transformation of an interface is constructed and tested. We had to construct and test the transformations in a parallel branch of the code repository from the main development stream. When the transformation was fully tested, then it was applied to the main code stream in a single operation.

        Less than 35 bugs were found in the 17,100 changes. All of the bugs were quickly resolved in a three-week period.

        If the changes were done manually we estimate that it would have taken 8,500 hours, compared with 235 hours to develop the transformation rules.

        The task was completed in 3% of the expected time by using Rewrite Rules. This is an improvement by a factor of 36."

        from “Transformation of an application data layer” Will Loew-Blosser OOPSLA 2002

        http://portal.acm.org/citation.cfm?id=604258

      • randomdata 10 days ago
        > but there are no large smalltalk projects for two reasons:

        But mostly because it was expensive. Objective-C and Ruby got you halfway there for free, and there is nothing developers love more than something that is free.

        • igouy 10 days ago
          (Elephant in the room) Free-as-in-beer Java!
      • ReflectedImage 10 days ago
        Well it's a lack of training problem.

        Someone properly trained with something like Smalltalk will on average output 3x the amount of software as someone trained on something like Java.

        There are big advantages to doing it.

        • EMM_386 10 days ago
          > Well it's a lack of training problem.

          The industry spends billions of dollars on developers writing Java. If they could spend 3 times less by simply training developers to use Smalltalk instead, they'd be doing it.

          They're not, because that's not the problem.

          • randomdata 10 days ago
            > If they could spend 3 times less by simply training developers to use Smalltalk instead, they'd be doing it.

            No they wouldn't. While not bad long-term thinking, by the time developers are up to speed with Smalltalk and realizing three times the output, the competition using the ecosystem its developers already knew will have launched something and won over the customers. It doesn't matter how much software you can crank out after you've already lost.

    • sebstefan 10 days ago
      It solves the problem of having your type mismatches happening at runtime as exceptions and weird behaviors when they could be happening at compile-time as a type error instead

      I've worked with both Javascript and Typescript and the ease of patching up Typescript projects you're not familiar with is unmatched compared to Javascript. At least when my code compiles, I'm sure the plumbing is correct

    • vundercind 10 days ago
      > JavaScript has lots of wacky problems but its main advantage to me was the loosy goosy approach to types.

      It runs in the browser. That’s always been its only advantage. Even now that it’s much better than it used to be: still true.

      > Not sure why nobody built something like reentrent exceptions or cool stuff like that, instead they built a stupid jail that down compiles to unreadable sludge.

      TIL machine-readable and -verifiable versions of the documentation you should be writing anyway (but probably aren’t) is a jail.

      Also one of the reasons I didn’t worry about it going the way of other compile-to-JS languages is that it’s output is nearly identical to what I would have written anyway, so it’s got a clean and easy “escape hatch”. But maybe I write unreadable sludge.

      • tom_ 10 days ago
        I've had it generate some verbose stuff when using .?, along these lines:

            (_c = this.log) === null || _c === void 0 ? void 0 : _c.withIndent('    ', () => {
                var _a;
                // (pointless ?. silence eslint)
                (_a = this.log) === null || _a === void 0 ? void 0 : _a.pn(`Buffer address: 0x${utils.hex8(bufferAddress)} `);
            });
        
        This was originally this:

            this.log?.withIndent('    ', () => {
                // (pointless ?. silence eslint)
                this.log?.pn(`Buffer address: 0x${utils.hex8(bufferAddress)} `);
            });
        
        If you have a long chain of ?., perhaps it gets really ugly.
        • fallingsquirrel 10 days ago
          It's just downleveling the syntax so it runs in browsers that are too old to support `?.` (similar to what Babel would do). If you set your compile target to es2020 or later it will emit `?.` verbatim.
        • vundercind 10 days ago
          Oh no, they’ve added more features JS doesn’t actually support. Enums were one thing, this was… an extremely bad idea. I hope it’s not a sign they’re gonna move farther into being a separate language.

          [edit] oh no wait that’s in newer JS versions, you’re just “compiling” to a version that doesn’t support it. Update your target to a version that supports the feature you used and it should be fine.

        • madeofpalk 10 days ago
          Right - if you use a language feature that is newer than your compile target, it will compile down 'modern' syntax like that. I'm not sure what else you would expect.
          • tom_ 10 days ago
            The discussion topic was cases where the js output includes a bunch of extra junk, so this is just intended as an example of that! Mostly the output looks pretty much like the input.

            (The compile target in my case is ES2017, as configured in August 2018. I can probably update that.)

    • G3rn0ti 10 days ago
      I think the biggest advantage TypeScript gives is discoverability when using a language server driven development environment. Hover over a function and you’ll get its signature and doc string. This will work quite quickly due all of the type information pointing back to its definition. This kind of static analysis is impossible in a weakly typed language due to the fact a random variable could hold anything at runtime. In this case an IDE cannot help you much inside an unfamiliar code base.

      At my workplace a team of test engineers wrote an entire little test framework around our application. It‘s using webdriver.io under the hood but defines all test classes in type script. Everytime I need to inspect a failing test I open it up in my Emacs and jump around the test method definitions quickly and easily and enjoy inline doc strings popping up wherever I set my cursor on. So the task of fixing a test becomes quite easy despite not having written the framework. Back when we used JS or Perl this task used to be quite obscure.

      On the other hand when I see react applications written in typescript I become quite skeptical of the supposed architectural benefits of static typing in front end logic. While React applications were already difficult to grasp, static typing constraint make refactorings even more headachy and I receive Java‘s spring framework vibes constantly.

      • pjc50 10 days ago
        > I think the biggest advantage TypeScript gives is discoverability when using a language server driven development environment.

        +1: I'm much slower working in environments where I have to do this manually. This is why I've been infiltrating Python type annotations in our codebase.

    • IshKebab 10 days ago
      It sounds like you have simply not experienced the problems that loosy goosy types cause. They tend to be biggest when you're working on large projects and on other people's code.

      If you've only done small projects or projects where you are the primary author then you may not run into the issues. You essentially end up doing what Typescript does but in your head without writing anything down.

      The problems it solves are:

      * Bugs! It catches lots of bugs.

      * Navigating code efficiently. You can just click stuff to go to its definition or uses.

      * Refactoring code reliably. You can now rename variables without making mistakes.

      * Reading code. It can be extremely difficult to understand code without static types because you don't know what anything is or where anything goes unless you run it (which can be very difficult).

      Not Typescript, but as an example I was trying to understand some code in Gitlab like `auto_cancel_from_rules.merge(auto_cancel_from_config)`. "what does `merge` do?" I wondered.

      Literally could not find it. You can't search for `merge`, way too many results. I don't know what the types of the variables are so I can't look it up. I spent about 15 minutes looking around and eventually gave up.

      With static types you can literally just click it and it will take you to the definition.

      • jerf 10 days ago
        If I never again in my career have to encounter the God Function that everything in the system calls one way or another and takes 9 arguments, all of which are something like "either a string identifying an ID, or a function yielding a string, or a function that yields a list or an iterator of strings, or an object with a GetID method, or if the third parameter was falsy, a function to be called if the user is not authenticated", I will be pleased. Or the function that has literally 40 parameters, 36 of them optional, and while each of them may be individually reasonably well defined you will never work out what all combinations of them do, and you can also know there is no test and no spec for all possible combinations. (Unlike the former which is characteristic of local codebases and bad discipline, the latter is the basis of major dynamic scripting language libraries.)

        Dynamic typing doesn't have to get that messy, but it takes discipline that is very hard to enforce at scale. Static typing can sort of approximate that level of mess but it takes a lot more work, and perhaps even more importantly, it's a lot safer to fix. But every significantly-sized dynamic scripting code base I've encountered has certainly had at least one of those two issues deeply, deeply ground into it.

      • randomdata 10 days ago
        > Bugs! It catches lots of bugs.*

        Unlikely. Maybe if you are using a language with a complete type system (let's face it, you are not), but otherwise you are necessarily going to have to encode all the type information into your tests anyway, so you haven't gained anything on this front. A partial type system cannot replace these tests.

        Your other points are the real wins, though.

        • IshKebab 10 days ago
          I didn't say it catches all bugs. I said it catches lots of bugs, which it absolutely does.

          It's literally impossible to write tests to find all bugs. Most tests don't come remotely close to that, so there's always going to be bugs that static type checks find that tests don't.

          There's a great paper that shows that even after tests, Typescript would catch 15% of Javascript bugs: https://earlbarr.com/publications/typestudy.pdf

          Also the fact static typing eliminates entire classes of bugs means you need to write far fewer tests. I've seen Python tests that literally fed different types into functions and verified that they accepted them. What a misguided waste of effort!

          • randomdata 10 days ago
            > I didn't say it catches all bugs.

            It is always telling when someone starts getting worked up about something, especially when that something wasn't even said or implied.

            > Also the fact static typing eliminates entire classes of bugs means you need to write far fewer tests.

            You don't need to write any more tests in the absence of static types. The purpose of testing is not to act as a replacement for static types and if you find yourself writing tests just for the sake of testing types, you know you're doing something horribly wrong. But, you necessarily have to encode type information into the tests in order of them to execute. After all, if that wasn't the case, you wouldn't even be able to catch bugs with a type system. As such, you gain that indirectly.

            > I've seen Python tests that literally fed different types into functions and verified that they accepted them. What a misguided waste of effort!

            Sure, I've seen developers do all kinds of stupid things too. In fact, give them Typescript and they will just litter the code with `any` everywhere – something I've witnessed far too often. There is no technical solution to bad developers. Was there supposed to be some meaningful takeaway here?

            • IshKebab 10 days ago
              > You don't need to write any more tests in the absence of types.

              To achieve the same level of quality, yes you absolutely do. This is actually a fairly fundamental fact about static typing. Static typing is a weak form of formal verification, or equivalently formal verification is just really really strong static typing. Clearly you don't need to write as many tests for formally verified code. The same is true (to a lesser extent) for "ordinary" static typing.

              > Sure, I've seen developers do all kinds of stupid things too.

              It's not stupid if you have a static typing system available! The stupidity was relying on tests to verify types, instead of ... you know, the thing whose whole purpose is to verify types.

              • randomdata 10 days ago
                > This is actually a fairly fundamental fact about static typing.

                If you have a complete type system. But as we are specifically talking about partial type systems, you have to already cover all your bases for where the type system is lacking, and by virtue of that you are going to overlap with what the type system also covers.

                > It's not stupid if you have a static typing system available!

                There is no reason for it, static type system or not.

                • IshKebab 10 days ago
                  > If you have a complete type system.

                  Nope. You don't need a Turing complete type system.

                  • randomdata 10 days ago
                    Complete, not Turing complete. How on earth did you manage to add an entire new meaning into the discussion that wasn't there before? I'm getting flashbacks of the earlier comment that started randomly going off on some weird tangent about how tests don't catch all bugs.

                    Anything to avoid the actual topic at hand, I guess?

        • agos 10 days ago
          it catches them before writing tests, which is a clear win
          • randomdata 10 days ago
            Except you need to write the test first, else there is no way to ensure that your tests actually work and aren't passing because your tests have bugs. So what have you won, exactly?
            • IshKebab 10 days ago
              It's much faster to find bugs because an IDE instantly underlines the exact line where the mistake is as you write it, than it is to write a load of code and then debug failing tests.

              And as I said in the other comment, tests won't catch all of the mistakes that static typing will catch anyway.

              • randomdata 10 days ago
                If you have a complete type system, sure. Then you have constraint on the subtle mistakes one is likely to make.

                The partial type systems found in languages people actually use, though, only constrain the most glaring of mistakes that you are almost never going to make. Not impossible that you could make one, but highly unlikely. Certainly not on the order of "lots". More like once in a blue moon.

                Refactoring is a different story. Having an editor that lights up like a Christmas tree when code changes breaks existing relationships is a huge boon, and with good refactoring tools you almost never have to break the relationships in the first place. This is where (partial) static typing truly shines.

                • IshKebab 10 days ago
                  > the most glaring of mistakes that you are almost never going to make. Not impossible that you could make one, but highly unlikely. Certainly not on the order of "lots".

                  Not true. People make these mistakes all the time.

                  I was literally reviewing code today where someone write Python code to write a field that didn't exist. They didn't realise because they hadn't written a test. They asked me to check if it fixed my issue, which wasted 5 minutes of my time checking, when an IDE with static types would have told them their mistake instantly.

                  You can pull the "well I don't make mistakes" classic, but it doesn't matter. People do make these mistakes.

                  I linked an empirical study showing that 15% of bugs are precisely these mistakes. If you don't think it's worth eliminating 15% of bugs then frankly I just think you have crazy priorities and I can't really fix that.

                  • randomdata 10 days ago
                    > They didn't realise because they hadn't written a test.

                    If someone hates future developers so much that they wouldn't write a test, why would they suddenly take care to write proper types? I've worked with those kind of people before. The reality is that they won't define any specific types either, relying on `any` (or whatever the language's equivalent is) to minimize the social footprint.

                    > They asked me to check if it fixed my issue

                    I get you work with an asshole who hates other developers, but why would they need to ask if it solves your issue when they can just run the tests you wrote to assert the issue you discovered? Well, okay, being an asshole they maybe just wanted to see what meaningless busywork they could force you to do, but then why didn't you at least run your tests rather than spending minutes hunting up and down for something that your test would have found instantly? Something doesn't quite add up here.

                    > when an IDE with static types would have told them their mistake instantly.

                    And most likely even an IDE with type inference, a la the original article. Did you even apply a type checker when faced with this problem? It would be quite ironic if you didn't.

                    > when an IDE with static types would have told them their mistake instantly.

                    As would the test, at least for any developers who don't have an intense hatred for other developers.

                    • igouy 10 days ago
                      "hates future developers" "those kind of people" "an asshole who hates other developers" "being an asshole" "intense hatred"
              • igouy 10 days ago
                Write a little bit of code and debug one failing test? TDD?
            • agos 9 days ago
              I don't "need" to write test firsts. TDD is one good way of writing software, but not the only one and not a requirement to write good software.
    • eternityforest 9 days ago
      Type checking has caught SO many bugs that would otherwise have taken a 30 second test to find. The time savings really adds up, and it catches a fair amount of bugs that otherwise would have made it to prod.

      To me it's one of the top requirements for a modern language.

    • wruza 10 days ago
      It’s practical. You change your structures and forget places to fix. Typescript trying to solve that.

      Edit: Also you can follow typedefs of a library and make sense of it without relying on its documentation quality or deciphering the code.

    • stiiv 10 days ago
      In my opinion, JavaScript's main advantage is that it can be run in browsers in addition to other (i.e. server) environments.

      If you're building something simple, and the type/shape of function parameters is either very obvious or very well-guarded, TypeScript's returns diminish.

      However:

      As a reviewer of complex code, I want to see annotations so that I can better understand what I'm reviewing.

      As an author of complex code, I want to clearly communicate the intent of functions I write, so that they are not misused by other developers.

      As someone who supports the use of my software, I want to reduce errors by guaranteeing the correct types/shapes of function arguments.

      ...and I'm just getting started. These are all very compelling needs in my experience.

    • Vinnl 10 days ago
      > that down compiles to unreadable sludge.

      I think there might be a couple of other tools around in your setup (that might influence your feelings). TypeScript mostly just strips out type annotations, so the output looks pretty close to your input.

    • imetatroll 10 days ago
      I have never had typescript really get in my way and it does have an escape hatch if you need it so, personally, I would always prefer to use it.
    • verelo 10 days ago
      This is so my experience. Also when you can just declare something as “any” and effectively say f it to the entire concept they’re trying to enforce…what’s the point? From time to time human nature takes over and you use any, and the disease has started the spread. If i wanted loose types, i wouldn’t have used typescript. So “pick a side” is all i can ever think when i work with ts.
      • tom_ 10 days ago
        You need a getout clause sometimes, and it's useful to have one. (You should prefer "unknown", though, which requires you to cast the value on each use, over "any", which treats the value as being of all possible types. You can configure eslint to moan at you if you use "any": https://typescript-eslint.io/rules/no-explicit-any/)
      • vundercind 10 days ago
        “Any” is incredibly useful. It lets you transition JS code to TS without having to do the whole thing at once. It lets you work with libraries written in JavaScript without having to immediately find or write types for them. The language would be nearly unusable in the real world without it, and that’d have been even more true in its early days.
      • seper8 10 days ago
        You know you can do loose types in C# and many other "strongly typed" languages too?
      • wruza 10 days ago
        The point is you have most things covered and that one that is too complex to type you ignore and rely on softer contracts there.