[HN Gopher] Insights from Adopting TypeScript at Scale
       ___________________________________________________________________
        
       Insights from Adopting TypeScript at Scale
        
       Author : robpalmer
       Score  : 102 points
       Date   : 2020-11-10 07:25 UTC (1 days ago)
        
 (HTM) web link (www.techatbloomberg.com)
 (TXT) w3m dump (www.techatbloomberg.com)
        
       | coding123 wrote:
       | I've seen some shops do things like this. Making their own tools
       | to get around odd shitshows they've gotten themselves into. I
       | suspect that there are a number of people within the org that
       | aren't fans of Webpack or some other set of tools that would have
       | made some of their decisions end up with the consequences in the
       | article. They didn't quite state it but I suspect they're trying
       | to use a specific stack instead of a more obvious stack to make
       | typescript work.
       | 
       | edit: just adding though, that this isn't surprising with a dev
       | base of 2000 js developers.
        
         | robpalmer wrote:
         | It's more about setting up the guard-rails ahead-of-time to
         | avoid falling into a hole, rather than getting out of one. We
         | know the way to do this is to stick to standards like
         | ECMAScript.
         | 
         | ES Modules are the glue that binds the whole JS ecosystem
         | together. Whilst ESM is the standard, today a lot of people are
         | using ESM only as an authoring format that later gets converted
         | to CommonJS before being published or executed. Many of today's
         | tools rely on this, meaning the ecosystem is partially tied to
         | CommonJS. Migration is happening but it's slow and non-trivial.
         | 
         | In a way, we bypassed the CommonJS era and skipped directly
         | from AMD to ESM. AMD and ESM are pretty much isomorphic and
         | differ only in syntax. You just run a codemod to get from AMD
         | syntax to ESM syntax - semantics are preserved. Whereas the
         | step from CommonJS to ESM does not fully preserve semantics.
         | CommonJS module initializers are always synchronous. ESM can be
         | asynchronous - you can use `await` in the module initializer.
         | 
         | The article covers a few of the things we've done to retain a
         | very standard ES Module system that is ECMAScript compliant. I
         | think it is this pursuit of standards and desire for robust
         | interoperable packages that led to some of the surprising
         | discoveries.
        
         | kristaps wrote:
         | The article mentions they have around 2000 engineers, at that
         | scale investing in custom tooling can easily become a
         | significant net gain in productivity and stability, especially
         | when dealing with the JS ecosystem.
        
           | robpalmer wrote:
           | Agreed. The article touches on this. When you have hundreds
           | of projects that all target the same tightly-managed
           | evergreen runtime, there's not much justification for having
           | each project select and maintain a different toolchain. It
           | just leads to the same problems being solved over again, and
           | makes it harder for developers to switch between projects.
           | 
           | The fact that we can consider high-quality sourcemaps a
           | solved problem (during both debugging and consolidated crash
           | telemetry) really helps developers focus on building
           | functionality rather than debugging a build system.
           | 
           | I think most large companies have dedicated tooling teams for
           | these kinds of reasons. A related viewpoint in a related
           | thread: https://www.reddit.com/r/typescript/comments/jrgi8z/1
           | 0_insig...
        
         | JonathonW wrote:
         | I think the key here is:
         | 
         | > Back in 2005, the company started migrating those apps from
         | Fortran and C/C++ to server-side JavaScript
         | 
         | Since their use of Javascript predates Node (and the rest of
         | that ecosystem, like Webpack or Babel or whatever), they've
         | built up their own Javascript environment that doesn't rely on
         | Node or Node conventions at all. Not so much a "get around odd
         | shitshows" situation as much as a parallel evolution.
        
           | robpalmer wrote:
           | Yes - you deduced correctly!
           | 
           | There was a long period of parallel evolution. Over the last
           | few years we've been able to get back on the standards track.
           | The article describes this as one of the guiding principles.
           | It's why we participate in TC39.
           | 
           | Nowadays our tooling stack now uses TypeScript, Babel, Rollup
           | & Terser which I regard as the most mainstream of choices.
           | And we go out of our way to keep things aligned with
           | ECMAScript, e.g. preventing the use of
           | "experimentalDecorators".
        
             | jgalt212 wrote:
             | Bloomberg often gets accused of "not invented here"
             | syndrome. But often times in the past, it's been the case
             | that what they need hasn't been invented yet.
        
       | Chris_Newton wrote:
       | Interesting how much emphasis they seem to place on treating TS
       | as precisely JS + types and nothing more, even to the extent of
       | excluding evolutionary TS features.
       | 
       | That does seem a reasonable argument for avoiding enum types in
       | TS. Those have semantics that go beyond how enumerations work in
       | most languages and implementing them in the underlying JS is
       | going to introduce some runtime cost.
       | 
       | I wonder whether their coding standards still permit _const_
       | enums, though, as they are also new relative to JS but work more
       | like traditional enumerations in C-family languages. These ought
       | to be entirely compiled away, so it seems like the same arguments
       | around efficiency and portability /compatibility wouldn't apply.
        
         | robpalmer wrote:
         | There isn't much of a difference between regular `enum` and
         | const `enum` when it comes to the usage of the `enum` keyword.
         | The big difference is what they compile to - where const `enum`
         | evaporates by inlining the values into the usage sites.
         | 
         | `enum` is a keyword that is reserved in ECMAScript and
         | therefore may one day clash with TypeScript. It's unlikely any
         | ECMAScript-defined semantics for enum would match today's
         | TypeScript `enum`. So it's not on any standards track.
         | 
         | There is already a proposal for JS `enum` that has different
         | semantics to TS `enum`, and it was created by someone on the
         | TypeScript team: https://github.com/rbuckton/proposal-enum
         | 
         | So the const form doesn't really change the hazard.
        
       | mgdev wrote:
       | I thought Bloomberg was into Bucklescript/ReasonML. Warring
       | factions?!
        
         | Scarbutt wrote:
         | Can't beat better ecosystem, better integration with the
         | ecosystem and let other company(Microsoft) do the work for you.
        
           | robpalmer wrote:
           | The TypeScript ecosystem is amazing - partly because of the
           | large number of users also also because of the sense of
           | community. It is run as a true OSS project. Roadmaps are
           | release plans are all public on GitHub. Even as outsiders
           | we've been able to contribute significant features, e.g.
           | Private Fields in TypeScript 3.8.
           | 
           | https://devblogs.microsoft.com/typescript/announcing-
           | typescr...
        
             | agustif wrote:
             | Yeah TypeScript it's the only thing that makes me
             | hate/doubt M$ a little less...
        
               | robpalmer wrote:
               | What about VS Code?
        
               | mistersys wrote:
               | TypeScript was in the right place at the right time, and
               | the team prioritized the right features in the beginning,
               | allowing for the great adoption.
               | 
               | But I'd still place TypeScript firmly in the "worse is
               | better" category (products that are technically inferior
               | then the state of the art, but succeed due to
               | circumstance), it's a band aid on top of a the broken JS
               | ecosystem. Its ad-hoc, Hodge-Podge type system and poor
               | meta-programming is sad to see for such a popular
               | language.
               | 
               | I'd rather write TypeScript then JS, but as soon as
               | there's an opportunity to write software that works
               | across all platforms without dealing with JS, and with a
               | type system that's actually built on a solid foundation,
               | I'm taking it.
        
         | vamega wrote:
         | The bucklescript author now works for Facebook.
        
       | lemming wrote:
       | What is the proportion of JS libraries in the wild which provide
       | TS type declaration files, either via DefinitelyTyped or provided
       | by the lib itself? Is it normal to have to write your own
       | declarations, or do most libs provide them these days?
        
         | a_humean wrote:
         | Its actually quite rare to see a library without either first
         | or third party support these days. Many new libraries are
         | either written in typescript, or the authors have taken care to
         | create declaration files or contribute to definately-typed. If
         | a library reaches any degree of popularity it usually isn't
         | long before a third party declaration appears.
         | 
         | Older libraries that are long abandoned by their maintainers
         | usually don't have anything. At work we pretty much ignore all
         | libraries that don't have types from somewhere these days, but
         | that doesn't eliminate many things.
        
           | horsawlarway wrote:
           | I agree on ignoring libraries without definitions.
           | 
           | Having to write the definitions myself usually isn't a huge
           | pain, but it's a big red flag showing that it's probably
           | abandoned, and there's no community support around it anymore
           | (or possibly ever).
        
         | cutler wrote:
         | As an outsider I'm puzzled how any TS library repo keeps up
         | with the pace of change in TS. With JS you can more or less
         | write it once.
        
           | robpalmer wrote:
           | Whilst TS does technically contain breaks, these are normally
           | simple increases in the power of the type-checking. It's
           | finding more errors in code that previous seemed fine. Think
           | of it like adding more ESlint rules.
           | 
           | It's rare for there to be a breaking change in the JS emit.
           | 
           | The TypeScript team work hard to preserve compatibility.
           | Breaking changes are explicitly managed and communicated
           | ahead of time. There is a concept of a breakage-budget per-
           | release. This means if you stay up to date, the cost of each
           | upgrade should not be huge. Orta and Nathan on the TypeScript
           | team talk about this in this podcast episode:
           | https://dev.to/devteam/devnews-s1e4-typescript-4-0-gitee-
           | chr...
           | 
           | So "keeping up" is not too hard.
        
             | lemming wrote:
             | Do the breaks tend to affect the TS declaration files, or
             | are they more to the language itself?
        
               | robpalmer wrote:
               | The majority of breaks are due to the checker getting
               | better. So code that passed now errors. Most of the time
               | pre-existing published DTS files still operate fine.
        
         | geewee wrote:
         | Almost all of them provide them, although sometimes they are
         | slightly out of date. I think I've had to write my own
         | declaration files (or type a library as any) for one or two
         | libraries in years
        
       | darksaints wrote:
       | Oh wow they went from C/C++ to JavaScript? That's just trading
       | one dangerous footgun for another. Glad to see they finally found
       | a better tool. I can't function in JavaScript without
       | Typescript...I constantly have to be looking up docs cause I
       | don't have intellisense, and once something works I'm terrified
       | to ever touch it again. Typescript made front end development
       | reasonable again...not perfect, but not so pathetically bad that
       | I want to rage quit like I did before.
        
         | sjroot wrote:
         | C++ is still very much used, along with Python. These languages
         | are generally used for the overwhelming majority of our backend
         | services.
         | 
         | JS/TS are used in the Terminal's view layer. You _can_ make
         | services in these languages as well, AFAIK, but I don 't think
         | it is very common.
        
         | dboreham wrote:
         | Fashion.
        
         | Roboprog wrote:
         | That seems to be pretty common statement about JavaScript, but
         | strangely not one I share.
         | 
         | I have been programming since the early 80s, and my experience
         | with JS has been pretty positive, especially compared to the
         | slog through the unreadable mud that is enterprise Java. (If I
         | was going to rage quit on something, it would be the verbose,
         | obtuse, repetitive Java sludge I've had to read the last decade
         | and a half)
         | 
         | Typescript solves problems I don't have. The Jetbrains IDEs do
         | autocomplete just fine on vanilla JS, and the documentation
         | window automatically shows the initialization and any JSDoc for
         | most every symbol the editor cursor touches. I avoid writing
         | code with thousands of global symbols.
         | 
         | OOP languages like Object Pascal and C++ are good for making
         | lemonade from the lemon of manual memory management, but if you
         | have efficient garbage collection, use functional programming
         | techniques rather than OOP bloat, and many self inflicted
         | problems go away.
         | 
         | I hope TS doesn't turn JS into Enterprise Java, The Next
         | Generation.
         | 
         | Nothing personal, most people seem to prefer that style. Just
         | understand, there is a reason some people run away from the C++
         | / Java / C# / TS milieu.
        
           | nicoburns wrote:
           | Have you used TS much? In my experience idiomatic TS isn't
           | much different to idiomatic JS and a far cry from Java style
           | OOP code (the Angular ecosystem which was admitedly an early
           | adopter of TS is an exception and best avoided).
        
           | kingdomcome50 wrote:
           | > I hope TS doesn't turn JS into Enterprise Java, The Next
           | Generation.
           | 
           | No chance. And frankly, I don't get the comparison you are
           | making to C++/Java/C#. TS is fundamentally different than
           | those languages. From structural typing to a default
           | functional/imperative paradigm, it really is just JS with
           | better static analysis.
           | 
           | Your IDE is _not_ as good for JS as it would be for TS. The
           | entire impetus for TS is /was to provide better
           | tooling/ergonomics around JS. Whether or not you _need_
           | better tooling is a subjective matter.
        
           | IshKebab wrote:
           | > The Jetbrains IDEs do autocomplete just fine on vanilla JS
           | 
           | I find that hard to believe because it's not a solvable
           | problem without type annotations.
        
       | mirekrusin wrote:
       | "9. Generated declarations can inline types from dependencies"
       | 
       | Why do they generate .d.ts files instead of publishing .ts files
       | alongside .js files? This should solve inlining issue, no?
        
         | robpalmer wrote:
         | That's an excellent suggestion!
         | 
         | It's true you could just have every package publish the raw
         | TypeScript source-code. So that when an app imports a library,
         | it type-checks against the original source code of the library.
         | No need for DTS files from your dependencies!
         | 
         | I have never seen this done in practice for a large system.
         | It's not as scalable as using bare-minimum type declarations
         | that you find in DTS files. It requires more parsing, and
         | potentially more time to accumulate the types. Whereas DTS emit
         | in TypeScript can flatten the resulting type into the DTS file.
         | 
         | But if performance didn't matter, I think this would probably
         | work. And it would eliminate the class of bugs where the
         | generated DTS files are not 100% semantically identical to the
         | original source code. That's another edge-case finding I
         | omitted from the document but hope to write up another day.
        
           | mirekrusin wrote:
           | It works quite well, you can forget about src/ lib/
           | directories, just structure package as you want (ie files at
           | the root), generate js files along ts in the same directory
           | (relative paths to assets stay the same, import paths are the
           | same in js/ts, very useful), add in vscode rule to auto hide
           | .js file if .ts with the same name exists
           | `{"files.exclude":{" __/ *.js":{"when":"$(basename).ts"}}}` -
           | coding is pleasure, you just see and work with ts, no need to
           | generate js files most of the time (on prepublish yes) etc.
        
       ___________________________________________________________________
       (page generated 2020-11-11 23:01 UTC)