Skip to content

Instantly share code, notes, and snippets.

@dannycoates
Last active May 29, 2024 16:36
Show Gist options
  • Save dannycoates/adfce2a0b3a9812c8ba6a2312ef5b922 to your computer and use it in GitHub Desktop.
Save dannycoates/adfce2a0b3a9812c8ba6a2312ef5b922 to your computer and use it in GitHub Desktop.
Typescript Conversion Plan

A (proposed) plan for Typescript

“How did you go bankrupt?” Bill asked. “Two ways,” Mike said. “Gradually and then suddenly.”
  - Hemingway

Goals

  • Convert the olapui repo to Typescript leaving zero Flow
  • Minimal impact to concurrent feature work
  • Minimal transition period
  • No regressions
  • No surprises
  • Leave no one behind

There's no practical future to Flow. The industry has collectively chosen Typescript as the de facto Javascript type system. We need to move off it eventually. There's never going to be a particularly convenient time to do it but the longer we stay the more work it will take to move away from. There's no better time than now.

Transitions are hard. There's nothing worse than working on a codebase mid-transition. Fixing bugs with the old style, trying to write new things the new way, but having to mix it with old parts because you don't have time to rewrite the ten classes this new piece depends on. Two syntaxes, linters, type checkers, mixed imports, build steps; possibly for years. Woof! The faster and broader the transition the better.

The main reason to slow-roll a transition is because you can't afford to pause new development while it happens. Totally understandable. Thankfully, Flow and Typescript are close enough systems that the bulk of the transition can be automated. With thorough preparation and automation we can minimize the transition period while staying out of the way of new development.

We also must consider how our human workflows need to transition too. New syntax, idioms, tools - better tools. We want to be as confident and productive with Typescript on day one as we are with Flow now. There shouldn't be any surprises or confusion on how anything works.

Benefits

  • Wider selection and improved type safety with 3rd party dependencies
  • Can utilize modern Typescript features
  • Improved editor integration, esp VSCode, but also others
  • Better Copilot experience
  • Faster onboarding (probably)
  • Better long term support and outlook

Proof of Concept

I implemented a prototype branch that is able to build and run local dev in the browser successfully. It's my third trial run. It contains about 3k type errors with tsc - down from the over 5k of the first attempt. I'm optimistic that we can improve on that further to achieve a fast transition.

Phases

  1. Preparation
  2. Conversion
  3. Recovery
  4. Valhalla

1. Preparation

Gradually. This can be done in parallel to feature work. We should take as long as we need here but no longer.

There's some constructs in the current Flow codebase that make a direct conversion in it's current state difficult. A relatively small portion of code produces a high number of errors in the conversion. Refactoring some global data and cyclic structures ahead of conversion will make the recovery phase simpler. This can be an iterative process as preparation progresses as long as the changes integrate well into the existing Flow code. These changes should be merged individually as they're completed into the master branch as part of our normal dev cycle.

Any changes that don't integrate well but help with conversion can be delayed until conversion time (ideally scripted to allow the diff to be fresh and not need to track master) when the decision to convert is made.

We'll iterate on soft runs of the conversion, where we perform the conversion in an isolated env and check the results, increasing our confidence and reducing our cleanup in the recovery phase by updating code and documentation until we're happy with the result. Then we'll come up with our timeline for the remaining phases.

To track our progress we can automate a build workflow that produces a soft run on demand and outputs our error count along with a deployment of the code. We can use one of our existing weekly meetings to discuss progress and concerns on a regular cadence.

I, Danny, will be the primary dev in this phase, landing code, writing documentation, answering questions, and giving status updates. The decision to move to the next phase will be by consensus of the team.

Once we're ready to move forward we'll have a meeting to ensure everyone is ready for the next steps.

Meetings

  1. Kickoff (once)
  2. Progress (weekly)
  3. Preflight (once)

Artifacts

  • backward compatible code changes that make the next steps smooth
  • a soft run of conversion
    • ideally involves QA and a deployment env
  • documentation
    • TS guidelines
    • transition briefing
    • recovery plan
    • timeline

2. Conversion

Suddenly. The prep is done. We've honed the soft runs to a sharp edge. We make the cut.

In a single commit the project will be converted from Flow to Typescript. In the unlikely event our preperation didn't catch something catastrophic we can revert this commit to restore us back to Flow.

Artifacts

  • typescript codebase that builds and runs with no regressions
    • WILL still contain type errors
    • deployable to production

3. Recovery

We're still in a transition phase here, which we know sucks, so we should get out of it ASAP, but at least we're fully in our destination ecosystem and not straddling two worlds. New development can proceed unimpeded, except for deciding what to do about encountered type errors. If they're minor they can be fixed alongside the new code, or if they're larger they can be explicitly ignored (@ts-ignore) and noted as a priority in our recovery plan for follow up repair.

In prep we figured out how big a task this is and what our plan is. Now we just execute it according to the timeline.

Similar to prep we can have weekly progress updates and track our error count.

Meetings

  1. Phase kickoff / conversion retro (once)
  2. Progress (weekly)
  3. Retro (once)

Artifacts

  • type-error-free code
  • a solid base for testing and reliability

4. Valhalla

I just watched Furiosa. Anyway, we're done. On to the next thing!

Artifacts

  • cake
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment