-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Managing code compatibility in a TypeScript ecosystem with multiple compiler versions #25778
Comments
Thanks @mhegazy. Yes, I should have clarified that I'm interested in recommendations that are possible with today's tools. Adapting #22605 into such a thing, I believe it looks like this?
|
We have not had explicit guidance on this regard. what we have seen ppl do are either one of two approaches, 1. option a above, where the whole org moves their TS version all at once. 2. for libraries to test against older versions, and try to isolate the breaks from their users. Most of the breaks do not escape to the .d.ts files (with few exceptions). |
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed. |
Backward/Forward .d.ts compatibility system #31907 |
@igrayson what’s your final solution now? |
**Requirements** - [ ] ~I have added test coverage for new or changed functionality~ - [x] I have followed the repository's [pull request submission guidelines](../blob/main/CONTRIBUTING.md#submitting-pull-requests) - [ ] ~I have validated my changes against all supported platform versions~ No new functionality has been added (only types import/export refactoring). **Related issues** #345 #347 **Describe the solution you've provided** Remove the usage of [type modifiers on import names](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html#type-modifiers-on-import-names) to improve backwards compatibility with early versions of TypeScript. **Describe alternatives you've considered** The obvious solution would be upgrading the TypeScript version in the consumer, but this is not always easy (it's not in our case). [More info here](microsoft/TypeScript#25778).
We're looking for recommendations from the TypeScript team on the best way (with today's tools) to mitigate the organization-level developer pain of a large internal ecosystem with multiple TS versions, and whether you know of any existing approaches. I'm especially interested to hear stories of how other teams have concretely mitigated it (I link to one such below, from Google).
This isn't a TypeScript bug; I'm aware of #14116 and am not pushing for a fix from within TypeScript.
The pain
We have a growing number of TypeScript services that depend on a growing number of internal TypeScript libraries, and developers commonly hit against compilation failures caused by a mismatch in compiler versions between a consuming service or library and one of its (potentially transitive) dependency libraries.
While these pains are equally true for public and internal libraries, we're primarily interested in what we can do with the packages we have direct control over (i.e., we can mostly guarantee semver is followed).
We use npm (and yarn) for dependency management, we generally follow semver internally, and we haven't realized a perfect way to apply these tools towards the problem.
Problematic scenarios:
1. Consumer's compiler is older than dependency's compiler
This is the natural case where the dependency's compiler produced
.d.ts
code with language features that the consumer's compiler doesn't understaned.Usually, the resolution has been to upgrade the consumer's compiler.
2. Consumer's compiler is newer than dependency's compiler
Less obviously, this can also cause failure. Example: TypeScript 2.9 widened the type of the
keyof
operator, rendering some.d.ts
declaration code emitted by TypeScript 2.8 unimportable by a 2.9 compiler.Usually, the resolution has been to downgrade the consumer's compiler.
Solutions considered
In both scenarios above, the common resolution (upgrade/downgrade) is often complicated by the graph of mismatched compiler versions among all of the consumer's transitive dependencies -- a problem we anticipate to get worse as more libraries are built.
a. Enforce a single TypeScript
X.Y
version across the organizationUsing an npm postinstall script (or other), assert that every service and library builds with a single blessed
X.Y
version of TypeScript.Google does this (video), and they have some advantages that makes this realistic (a monorepo; centralized dev resources to grind out compiler upgrades).
Pros
.d.ts
compatibility, between internal packages.Cons
b. Bump library major versions for TypeScript upgrades
When a library upgrades the version of TypeScript used to build, also bump its major version. This doesn't fully solve the problem, but it reduces the chance that a consumer will break from a minor version update of a dependency. Breakage can still happen if the consumer/dependency are on different TS versions which are compatible for the subset of language features used in the dependency's old
.d.ts
files, but incompatible for language features in an interface added by a minor version update.Pros
Cons
This also doesn't provide developers with any guidance on how to navigate major version upgrades for their dependencies -- other than "update the package; run tsc; hope nothing explodes".
c. Libraries declare compatible consuming TypeScript compiler versions
Using a
package.json
key, have each library declare what TS versions it believes its emitted.d.ts
files can be imported by. Apostinstall
script throws if consumers are running an unsupported version (problem: without a yarn/npm lockfile, postinstall script can't be sure which TS compiler is actually in play)At its simplest (
package.json
key manually updated by developers) it's error-prone, but over time converges on useful guidance.Pros
Cons
Both (b) and (c) still leave service developers with the challenge of detecting the highest safe version of TS for their service, and library developers with the risk that they'll need support multiple branches for consumers with (very) different TS versions.
The text was updated successfully, but these errors were encountered: