It might be nice if it were possible for a package to declare the minimum TypeScript version that its consumers must use.
The closest I've come to that is to use typesVersions
to conditionally serve type declarations that deliberately don't compile under TypeScript versions other than those I support. For example:
minimum-typescript-version.ts
/**
* @module
* This module is intended to enforce the minimum TypeScript version we support, by not compiling under earlier versions.
*/
/**
* Const type parameters were introduced in TypeScript 5.0.
*
* Under TypeScript 4.9:
*
* > error TS1139: Type parameter declaration expected.
*/
export default function<const _>(_: "TypeScript 5.0 or later is required.") {}
package.json
{
"name": "the-package",
"typesVersions": {
"<5.0": {
"*": [
"./dist/minimum-typescript-version.d.ts"
]
},
"*": {
…
}
},
}
A TypeScript 4.9 consumer that attempts to import any export from the package in question, whether that export contains TypeScript 5.0-only syntax or not, will get this error:
Complete error message
node_modules/the-package/dist/minimum-typescript-version.d.ts:12:26 - error TS1139: Type parameter declaration expected.
12 export default function <const _>(_: "TypeScript 5.0 or later is required."): void;
~~~~~
node_modules/the-package/dist/minimum-typescript-version.d.ts:12:33 - error TS1005: ',' expected.
12 export default function <const _>(_: "TypeScript 5.0 or later is required."): void;
~
node_modules/the-package/dist/minimum-typescript-version.d.ts:12:36 - error TS1005: ')' expected.
12 export default function <const _>(_: "TypeScript 5.0 or later is required."): void;
~
node_modules/the-package/dist/minimum-typescript-version.d.ts:12:76 - error TS1005: ';' expected.
12 export default function <const _>(_: "TypeScript 5.0 or later is required."): void;
~
node_modules/the-package/dist/minimum-typescript-version.d.ts:12:77 - error TS1128: Declaration or statement expected.
12 export default function <const _>(_: "TypeScript 5.0 or later is required."): void;
~
node_modules/the-package/dist/minimum-typescript-version.d.ts:12:83 - error TS1109: Expression expected.
12 export default function <const _>(_: "TypeScript 5.0 or later is required."): void;
~
That means one can make it obvious to consumers if they have a non-supported TypeScript version, instead of flooding them with the wall of text that TypeScript tends to print in the presence of syntax errors.
This scenario is particularly interesting:
the-package
drops support for TypeScript <5.0 in version 42.0.0, but doesn't yet use const
type assertions, so the emitted code still happens to work under older TypeScript versions.
- A consumer using TypeScript 4.9 upgrades
the-package
to version 42.0.0 and notices no breakage, so they think everything is fine.
the-package
starts using const
type assertions in version 42.1.0. Now the emitted code suddenly does need TypeScript 5.0 or later to work.
- The consumer upgrades
the-package
to version 42.1.0 (maybe indirectly via a transitive dependency) and suddenly gets curious syntax errors.
To prevent that, it might be nice if version 42.0.0 really did break consumers' builds, in a clear and descriptive way.
On the other hand, the above approach is quite hacky, and it may mean that some consumers won't be able to use the package, even though it — or at least some of its exports — would have worked perfectly fine.
But I think it's worth having a discussion around this at least: is it possible to declare and/or enforce a minimum supported TypeScript version, and should packages do that?
I might just be overthinking this of course. Hopefully someone will enlighten me!