10 ms·
Migrating 300k LOC from Flow to TypeScript
- paulddraper 7y agoSimilar decisions to what we made at Lucidchart 2 years ago for migrating 600 KLOC of Closure to TypeScript. [1] (Closure is a venerable JavaScript type system by Google using JSDoc-like annotations.) Stop the world migration, automated scripts, manual fixes, lots of ts-ignore/any. And thoroughly worth it. [1] https://www.lucidchart.com/techblog/2017/11/16/converting-600k-lines-to-typescript-in-72-hours/ https://www.lucidchart.com/techblog/2017/11/16/converting-60...
- vosper 7y agoHow do you feel about Typescript 2 years after switching? Anything that you wished you known before, that you've had to learn on the way?
- paulddraper 7y agoThe largest change was actually going from Closure modules (namespaces) to ES6-style imports. TypeScript just keep getting better and better. I am looking forward to better Google Bazel support for TypeScript to help with monorepos.
- z1mm32m4n 7y agoThe important parts here are (1) that they remained metrics driven and (2) that they focused on repeatability. 1. Both TypeScript and Flow are gradual type systems. They both explicitly allow escaping the safety and coverage of a type system, either to allow easier interop with existing JavaScript packages or to allow existing JavaScript codebases to incrementally adopt types. So there are always holes in which errors are reported, regardless of whether they had to silence some explicitly or not. By measuring the extent, they have a yardstick against which they can drive further type adoption. 2. Repeatability is the only way to do large code migrations. Write the steps in a script, run it, find the bugs in the script, fix the script, and repeat. With 300k lines of code no doubt they have dozens or hundreds of people committing daily. So a script is the only way to sneak in during off-hours, get something in that doesn’t race to conflict with someone else, and land the change. A long running, manually crafter branch here would not work—it would effectively operate as a fork of the codebase for the entire duration of the migration, with all the downsides that a fork entails. Kudos to the team; this is a very impressive feat!
- deleted 7y ago[deleted]
- truth_seeker 7y agoI really like the way TypeScript approaches Dynamic world of JS ecosystem with various advance types. https://www.typescriptlang.org/docs/handbook/advanced-types.html https://www.typescriptlang.org/docs/handbook/advanced-types.... Intersection Types - An intersection type combines multiple types into one. Union Types - A union type describes a value that can be one of several types Type Guards - A type guard is some expression that performs a runtime check that guarantees the type in some scope. Nullable types - compiler level safety for "can be a null " implication of any type Type alias - as the name suggests String literal types - Union type of few string values Numeric literal types - Union type of few numeric values Enum Member Types - enum members have types when every member is literal-initialized Discriminated Unions - You can combine singleton types, union types, type guards, and type aliases Index Types - you can get the compiler to check code that uses dynamic property names Mapped Types - Transforms each property in the old type in the same way to create new type. Conditional Types - selects one of two possible types based on a condition expressed as a type relationship test
- orta 7y agoNice overview! I plan on building a larger version of this into the docs eventually https://github.com/microsoft/TypeScript/issues/31983#issuecomment-503667997 https://github.com/microsoft/TypeScript/issues/31983#issueco...
- jillesvangurp 7y agoI recently spent some time introducing typescript to a javascript code base. My background is mostly backend/JVM, so I wasn't the perfect person to be doing this obviously. But as there was nobody else and I needed to own this stuff, I put in the work and got things done. My impressions are mostly positive in the sense that if you are doing JS, you are better off doing TS. The tooling is great and you can start with simple changes that almost immediately start giving clear benefits in terms of typing related warnings and other improvements. Typescript is minimally intrusive in the sense that all js is valid ts and you can gradually improve it by adding type annotations and addressing warnings. The benefits are a vastly improved safety net at a very minimal cost, smarter tools, and more confidence that a given piece of code will not break with some entirely preventable error (like an NPE). Excluding whole categories of bugs is a good thing. For new code, I consider it a no brainer. Most new projects seem to default to using typescript so I guess more people have come to the same conclusion. Lots of upsides, no real downsides that I know off. You'd have to be pretty stubborn to opt out at this point. For older code that you still care about, migrating is a good investment as well: you will improve the code. Any other code you probably need to get rid off anyway. That being said, I believe typescript is merely a gateway drug. Typescript is great and you definitely should use the strict mode. But even in the strict mode it still inherits a lot of cruft from javascript and this makes life needlessly hard. Other languages don't have this problem and the progression from the js/ts ecosystem to other things is very obvious with some younger full stack engineers I've known for a few years. Go and Rust seem particularly popular lately. And even Kotlin seems to be well liked (big fan myself). Better still, a lot of these languages are coming to the browser (via WASM or transpilation). Inevitably, some projects will start moving away from defaulting to the js/ts ecosystem for frontend work. Right now you'd be a very early adopter but things are improving rapidly and there are some early adopters. I played a bit with kotlin-js recently and while it still has lots of rough edges, it actually works quite well. Not quite a drop-in replacement for typescript just yet but most of that is related to consuming javascript from kotlin; which I'd argue is short term needed but long term undesirable and likely to become less important as native kotlin frameworks emerge (e.g. kvision is a popular one). Tip, parcel recently added kotlin support; works without extra configuration even.
- untog 7y ago
- cryptica 7y agoI've been using TypeScript for over 1 year after 10 years of JavaScript and I really don't like it. It slows me and the team down and creates more problems than it solves. It doesn't even ensure type safety because there is no runtime type validation for JSON objects received from the API. It's disturbing that so few people can see how useless it is. To me, it's extremely obvious. TypeScript is a hack of epic proportions and every so often the reality rears its ugly head in the form of failed source mapping, version compatibility issues, unexpected types during runtime, poor architectural decisions aimed at pleasing the compiler instead of fulfilling project goals. TypeScript is a very poor way to model real-world systems because it incorrectly assumes that real-world entities have a fixed type schema. This is obviously wrong. Real-world objects change over time and most things cannot be categorised clearly. A tadpole turns into a frog and learns the ability to walk. Some people are disabled and cannot walk. Some cars have 6 wheels. There is no fixed type schema for anything in the real world; it is filled with anomalies so why should we design systems to model such unrealistic objects? Why not force the developers to account for as many cases and schemas as possible, it's our job!
- paulbrittain 7y agoOur experiences are totally opposite. I find your opinion bizarre...
- cryptica 7y agoSo you're saying that on your planet TypeScript has runtime type validation?
- paulbrittain 7y agoI'm saying our experiences are totally opposite and that I find your opinion bizarre.
- cryptica 7y agoActionScript 3 was one of my first programming languages and I used it for many years; it's also based on the ECMAScript standard and very similar to TypeScript so I should be biased to like TypeScript, but I really don't. I was a big fan of static types for many years (I also did Java and C++) so I understand your point of view perfectly but I also understand that it is incorrect. The fact that my POV seems so bizzare suggests that you haven't considered it thoroughly before.
- vimslayer 7y agoThere have been a few posts like this, and the discussion always seems to focus on plain JavaScript vs TypeScript. I'd like to see some talk about Flow vs TypeScript instead. We have what I'd call a medium-sized project (~30k loc) written with Flow and TypeScript's superior tooling is indeed attractive enough that we too have been thinking about making the switch. Having used both, there are a few features in Flow that I'd miss. I think classes being nominal is a good approach and the ability to declare new nominal types is useful. Otherwise Flow's type system is structural, like TypeScript's. Function parameter type inference is also very nice feature, so I can make simple module- or function-local helper functions without needing to specify the parameter types explicitly. Having a syntax for specifying parameter variance allows for a more sound type system in some areas. Performance has historically been pretty bad but it's been getting better with every release. The tooling has also seen some improvements after Facebook nuked their own Nuclide-editor project and moved on to endorsing Language Server Protocol and VSCode. It's still far, far behind TypeScript, though. It's also a bit worrying that the community seems to be getting smaller, not bigger, with posts like this popping up.
- z1mm32m4n 7y agoIronically, one of the easier ways TypeScript has been able to work quickly is by skipping the type inference Flow does. It’s a trade off. The Flow team was advised that this approach would have performance problems early on in the project, and opted to focus on type system features first and perf second.
- shados 7y agoFlow's perf issues has more to do with bugs than anything. Its usually pretty near instant even on big projects, but do one little thing wrong somewhere that hits an edge case and everything goes to hell and you'll never find where it came from.
- vimslayer 7y agoA few more random thoughts that popped into my head: Flow's Windows support is pretty buggy. We have some team members who prefer Windows as their dev machine and it looks... painful. Flow supports the upcoming `?.` operator and overall they seem more open to introducing features that are in a development phase and might be changed/deprecated in the future. I guess it's a matter of perspective if that's good or bad, but man I'm going to be sad if we end up making the change and I have to convert all those nice and clean `foo?.bar?.baz` chains into some unreadable multiline monstrosity or calls to some random getter library. Flow's exact object types [1] are really useful and have prevented actual bugs when used with optional properties. TypeScript's concept of "freshness" [2] does prevent many if not most of these bugs though. [1]: https://flow.org/en/docs/types/objects/#toc-exact-object-types https://flow.org/en/docs/types/objects/#toc-exact-object-typ... [2]: https://basarat.gitbooks.io/typescript/docs/types/freshness.html https://basarat.gitbooks.io/typescript/docs/types/freshness....
- orta 7y agoSomewhat hijacking this thread to say that if you have ideas for improvements to TypeScript's documentation or website, we're currently asking for ideas: https://github.com/microsoft/TypeScript/issues/31983 https://github.com/microsoft/TypeScript/issues/31983
- munchor 7y agoI recently underwent a very similar experience at MemSQL[1] but for only 30K LOC. The pain points that led us away from Flow to TypeScript seem to be the same as the ones as Quizlet's . Overall, I'm very happy to see more and more teams move to TypeScript as a direct consequence of its Babel 7 support. TypeScript makes more sense as a pure type checker and not as a full blown transpiler. It's also interesting to see that their type coverage increased from 66% to 86% (ours increased from 88% to 96%). This pattern is probably because of better third party type definitions. I still prefer Flow's Type Inference and philosophy over TypeScript's, but in practice TypeScript is much better pretty much any use case I can think of. [1]: https://davidgomes.com/porting-30k-lines-of-code-from-flow-to-typescript/ https://davidgomes.com/porting-30k-lines-of-code-from-flow-t...
- vicapow 7y agoThere is not a 1-1 metric for "coverage" across these two systems. For exmaple, TS believes this code is "covered" but Flow knows it's not safe: type A = { readonly prop: number }; type B = { prop: number }; function func(f: B) { f.prop = 20; return f; } const a: A = { prop: 10 }; func(a); // no error?
- sdegutis 7y agoI've been a big fan of TypeScript for a few years, but lately I've been Considering Removing Typescript[1] from my project, because it seems to have just as many drawbacks as benefits, and the freshness of pure JavaScript is starting to look appealing again. But I haven't heard anyone take this perspective and I'd be really curious to hear people's thoughts on this idea. [1] https://sdegutis.com/2019-06-20-considering-removing-typescript https://sdegutis.com/2019-06-20-considering-removing-typescr...
- chaostheory 7y ago> Browsers don’t support it, so it adds an extra build step. Type-completion has gotten slower the bigger our project gets. This is something a faster computer can mitigate. Also I would compare the time you spend guessing what parameters actually are in vanilla JS vs the seconds you lose waiting for a Typescript build. Silicon time is much cheaper than carbon time. I don't understand how anyone doesn't use Typescript for large projects. Javascript is just too lenient. It doesn't even complain when you're not matching a method signature that you call; you can't even catch these ninja errors let alone explicitly know they dropped on you. There's a lot of value when you have a system that adds more checks and validation before runtime.
- sdegutis 7y agoThat's the general consensus and how I mostly feel too. But I'm starting to feel like the drawbacks might possibly be outweighing the benefits.
- chaostheory 7y agoIf we were talking about Ruby or Python, you'd have a stronger point. However Typescript's benefits far outweigh its drawbacks in light of Javascript's excessive lenience. Since, you're complaining about types, have you made good use of Typescript's interfaces and class inheritance? They're pretty powerful and even more flexible than something like Java.
- 7y ago
- lacker 7y agoMy only real pain point with TypeScript so far is with a codebase where some parts run in Node, some parts run in the browser, and some parts are libraries that can be imported by either. The best solution I have found is to separate out all TS code into three directories and have multiple tsconfig, but it often doesn't work nicely with the rest of the ecosystem.
- bytematic 7y agoI converted my work codebase to TS and it provided a lot more benefits than just types, including a greater understanding of the architecture. I was able to convert about ~400 files in around a week without any sort of plugins
- turadg 7y agoGreat planning and tooling work by our Web Infra team at Quizlet (Roger, Karoun, Jonathan) and all the product engineers. We're closely following this discussion so if you have any questions on some of the specifics we're happy to answer!
- masonic 7y agoSimilar story porting a similar volume of Flow code (MemSQL): https://news.ycombinator.com/item?id=18906405 https://news.ycombinator.com/item?id=18906405
- iLemming 7y agoI've been reading the comments, and sorry, I can't help it. Every time I read about (or try) some trendy thing in JS/Front-end world, I feel irritated and sad. Every single "big promise" hype that supposed to help us to "fix" issues with front-end development adds more complexity and frustration. jQuery was awesome, then "okay", then become bad, then later really, really bad. Same with Backbone. Same with Angular and Web components. Then Coffescript, Livescript, GorillaScript, IcedCoffeeScript and other "x-cripts", Dart, Typescript and Flow, Traceur and Babel. Then Grunt, Gulp, Browserify, WebPack. React came, and we got Flux, Redux, Redux Saga, MobX. And then some stuff that's actually not too bad for whatever reasons gets mostly ignored, e.g. Meteor, Ember, Cycle.js. I think fundamentally something deeply wrong with all that, and I don't know when and how we're going actually to fix it. After years of trying, I finally decided enough is enough and started looking for deferentially alternative solutions. I like Purescript and Elm. ReasonML looks promising. Currently, I'm using Clojurescript. It is not a silver bullet, but it is an astonishingly practical choice. I know - it won't work for everyone. The majority would dismiss it almost immediately (mostly for the wrong reasons). I'm not advocating for it. I'm just saying that I feel Typescript is not that magical pill that makes everything better. If you follow @garybernhardt on Twitter, I think he may feel the same.
- tekkk 7y agoSo you have seen the JS world progressing and feel sad about that they haven't just found out the "best way" from the beginning? I think it's marvelous how fast JS moves and outdated solutions are phased out in new projects for better and more reliable methods (although I admit some JS developers pick the wrong tools for wrong reasons). The act of having to constantly learn and think about a better way of doing things has at least kept me sharp and meticulously pondering the pros and cons of each way of doing things. Sure the churn can be discouraging and if you wanted to be able to write the same way with same tools to retirement I wonder why you'd even consider doing frontend development. I am quite happy with the tools I use (Typescript, React, Mobx, StyledComponents) and have felt no need to change for something else. They are tools I am very productive with, and all the developers I've worked with have been able to get quickly on track with using them. No huge mental leap from JS to TS as with functional languages like Clojure or Elm. Although it's my opinion that, JS itself should be eventually be phased out for something better for majority of frontend software. It just has too much old baggage so it would be best to just switch for something new completely. However, there's something mysteriously intriguing about JS in that allows so great flexibility, in good and bad, that not just any language can replace it. But nowadays I don't do much complaining about JS stuff anymore. I have found my sweet spot and I'm mostly just busy getting stuff done and there's things far worse in programming than how "bad JS is".