Skip to content

TypeScript 4 upgrade #16101

@joschect

Description

@joschect

Ported from hackmd

Problem description

Typescript 3.7 which builds react and react-northstar in the currently in the fluent repo is just over a year old. The current version is 4.1 (released mid-November).

In order to stay current we should invest time to upgrade the repo to Typescript 4.1.

This also unblocks setting up project references across the repo (as a follow-up project), which will provide a greatly improved dev experience when working across multiple packages.

Appetite

This is something that needs to be done to stay current with typescript and encourage partners to also modernize their own infrastructure. Previous initiatives to improve build infrastructure in the repo such as introducing project references were blocked by typescript bugs and could be tried again once the repo is upgraded to 4.0+.

This project is a good candidate for tag-teaming between time zones: work in a shared branch, and at the end of the day push your current progress and leave some notes about status/questions/next steps.

Solution

The main objective of this project is relatively straightforward that we should bump the current typescript version in the repo and get passing builds in all projects.

@fluentui/react has a hard constraint to maintain support for the typescript version for the latest release which for v8 is still 3.7.

Once we manage to get passing builds with 4.1 we would need a validation process for older typesript versions and perhaps release a beta for a partner.

The validation steps at least should be

  • Green CI for both N* and v8
  • Beta release of v8 on selected partners
    • TODO find good beta candidates with good CI
  • Beta release of N* on teams with green CI

We could also investigate libraries such as the downlevel-dts package to integrate with our build scripts to guarantee some form of backwards compatibility for older typescript versions.

In addition to upgrading TS itself, we'll need to upgrade some of our build dependencies which are specific to particular TS versions. This will definitely be the case with API Extractor and possibly also ts-jest, ts-loader, and maybe others.

Risks

The uncertainty of what is required to complete the upgrade is risk. Typescript doesn't offer backwards compatibility or follow semantic versioning, so it's easy to accidentally break partners. It also tends to provide stricter type checking each release, which is a good thing overall, but can cause migration pain (especially with the size of our codebase and complexity of some types).

This project is difficult to fully scope ahead of time and could take either a few days or a few weeks. Previous work on typescript in the repo has shown as much.

For upgrading tooling within the repo itself, some of the risks are as follows:

  • Upgrades typically start with a flood of errors which mostly have the same handful of root causes. These can be a bit time-consuming due to the volume, but straightforward.
  • After that, there are usually a few remaining tricky errors. The time to deal with these (or to determine that they're insurmountable without TS fixes) varies.
  • Sometimes there are excessive increases in either memory consumption or build time, which often require involvement from the TS team to debug. These can sometimes be worked around by tweaking our type definitions, but other times a TS fix is required.
  • Once things compile (with TS) successfully, we have to upgrade all the other tools (such as ts-jest, webpack loaders, API Extractor) to compatible versions. This may be uneventful or may reveal additional issues (including sometimes that a compatible dependency version hasn't been released yet).
    • This time, since our jest and webpack versions are both somewhat out of date, there's an additional risk that the versions of the deps which work with the new TS version won't work with our old jest/webpack versions.

Once we release, we may hear about additional issues from partners:

  • A backwards-incompatible typing change made it through, typically requiring a quick fix on our side. (This can be mitigated by adding a TS 3.7 validation step to our build and validating with a partner before merging.)
  • Something about the emitted code changed in a way that caused bundle size regressions. (Can be somewhat mitigated by validating with a partner before merging.)

There is also a risk of an extended validation period required for partners who would need support for older versions. We should not revert any TS upgrade changes if support for anything less than minimum supported version is required (currently 3.7)

Since 4.1 is quite new, it's possible it has some bugs which haven't been discovered/reported yet. It's still worth trying 4.1 first, but if we encounter any difficult issues which don't repro in 4.0, going to 4.0 for now is an acceptable fallback. (We can't go lower due to a bug in 3.9 which would substantially increase partners' bundle sizes.)

Another thing that wasn't clear from the documentation is whether we'll need to upgrade all the projects' tslib dependency to version 2.

Out of scope

The objective of this project is to replace typesript 3.7 with 4.1 and achieve backwards compatibility until 3.7 for dts files. All changes reflected should only contribute to this goal. Avoid making any other kind of build improvements until the upgrade is completed; any unnecessary changes could make this upgrade more painful.

The upgrade will be made in master only (not 7.0).

The typescript version under packages/web-components should probably stay the same since it's managed separately.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions