Description
Suggestion
🔍 Search Terms
lib
custom
environment
✅ Viability Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript codeThis wouldn't change the runtime behavior of existing JavaScript codeThis could be implemented without emitting different JS based on the types of the expressionsThis isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)This feature would agree with the rest of TypeScript's Design Goals.
⭐ Suggestion
If I understand correctly, currently the lib
option in tsconfig
can refer to a list of built-in lib declarations to configure the expected JavaScript environment. #44795 and #45685 (implemented via #45771) seem to partially allow customisation of this by pointing to a node module to override a given lib file, e.g.
tsconfig.json
"lib": "es2015"
package.json
"@typescript/es2015": "npm:some-custom-es2015-lib"
In some environments it would be helpful to be able to provide a non-standard lib file to extend what is available globally.
Would it be possible to support passing these directly to lib
and have them resolved via the usual package dependency route? In this case, custom-lib-module
would be a node module of the appropriate format.
"lib": ["es2015", "custom-lib-module"]
The additional hurdle beyond the module resolution, which #45771 added, is that this would allow values in lib
other than those in the list of values supported currently.
📃 Motivating Example
This change makes supporting custom JavaScript environments easier, by allowing easy sharing and extending of lib
configurations.
💻 Use Cases
I write JavaScript for use inside Cycling 74’s Max. This runs scripts in an environment with a significant number of custom global APIs (I guess comparable to how a browser environment extends the base ECMA standard). For lesser used environments like this, it would be unreasonable to expect TypeScript to provide built-in lib definitions (or even be aware of them), but being able to write, share, and consume custom lib
modules like this would be really helpful.
Current workarounds include:
-
I guess if Support resolving
@typescript/[lib]
in node modules #45771 is released in 4.5, it would be possible to hack around this by squatting on one of the official lib names, adding something like"@typescript/dom": "npm:custom-lib-module"
, but that seems suboptimal. (But — from a position of supreme ignorance — maybe points to a fairly easy path for implementing this?) -
Including the custom lib declaration files in
tsconfig.include
. This has the drawback of forcing use ofinclude
, which can complicate some set-ups and is not ideal intsconfig
files that are intended to be shared across projects. -
Using a triple-slash directive. This requires per-file inclusion, which is much less convenient than a project-level option.
Activity
DanielRosenwasser commentedon Sep 23, 2021
This can already be controlled with the
types
field, right?delucis commentedon Sep 23, 2021
That does work too, but using
types
blocks automatic consumption of@types
packages, right? (As per the docs.) For something that would ideally be a shareable config, this might be considered an unexpected side effect: why would using a different environment lib force you to be explicit about including other type packages if you weren’t previously?custom-lib-module/tsconfig.json
consumer/tsconfig.json
andrewbranch commentedon Sep 24, 2021
You could just
/// <reference types="custom-lib-module" />
in any file included in your project though?delucis commentedon Sep 24, 2021
You can, yes, but this requires per-file inclusion, which is much less convenient than a project-level option.
delucis commentedon Sep 24, 2021
A couple more thoughts regarding this approach.
If this were supported, perhaps the package.json resolution step in #45771 would be superfluous. Instead, tsconfig might include
"lib": ["npm:@types/web"]
or something similar?As an additional use case side note, I'm also thinking of the utility here for editor tooling for those less familiar with TS. If someone can get TS's autocompletion, hints etc with a standard shared config (potentially preconfigured in a domain-specific IDE), that would be nice. That's another mark against triple-slash directives.
andrewbranch commentedon Sep 24, 2021
No—the reason the package.json thing is important is that you need every existing reference to
/// <reference lib="dom" />
to point tonode_modules/@types/web
. You can addnode_modules/@types/web
to your program and not specify"lib": ["dom"]
today, but you’re screwed as soon as some other types package says/// <reference lib="dom" />
.delucis commentedon Sep 24, 2021
Ah, right! Yes, that makes sense.
andrewbranch commentedon Sep 24, 2021
Anyway, to your point about not liking
"types"
or triple-slash references, I think"include"
addresses your concerns about each of those? You’d have to specify node_modules as part of the path, which is unattractive, but not problematic as far as I know:"include": ["node_modules/custom-lib-module"]
delucis commentedon Sep 24, 2021
In my experience,
include
can complicate some set-ups and is not ideal in tsconfig files that are intended to be shared across projects. If a shared tsconfig is extended with a newinclude
, that overwrites the sharedinclude
right? And you probably have to extendinclude
to pick up the files in the project extending the shared tsconfig.custom-lib-module/tsconfig.json
consumer/tsconfig.json
delucis commentedon Sep 24, 2021
I’m not trying to be difficult here — I do get that this is kind of supported and I’m just pushing for a slightly cleaner/simpler/more shareable way of doing this, so I totally get if there’s no bandwidth for something like this.
orta commentedon Sep 24, 2021
I think this can just be solved pretty well with the current tools. We ship a bunch of 'import redirect'-y files in lib which will never change:
es5.full.d.ts
If you shipped:
All you would need is:
full.d.ts
:Then it would correctly override just the ES5 wrapped file, not touch any of the actual imports and add your own in the process as globals in any project (with that dependency set up)
Though I can empathize with the idea that there could be a lookup for
@typescript/globals
in node projects. It's an interesting idea.delucis commentedon Sep 24, 2021
OK, cool, that‘s kind of what I meant by “squatting” on a standard lib name, but reframed like this, perhaps that’s actually an intended rather than hacky use — you’re overriding/augmenting an existing lib, so that does fall into the #45771 use case. The fact this requires two configuration points across separate files that need to be kept in sync does still introduce more friction than I’d like, and the fact that tsconfig doesn’t clearly show the actual lib in use may be a source of confusion, but you can’t have everything in life 😃.
Thanks for taking the time to consider this anyway!