Skip to content
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

Proposal: Lookup lib files from individual node packages before falling back to builtin libs #45685

Closed
weswigham opened this issue Sep 1, 2021 · 8 comments
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript

Comments

@weswigham
Copy link
Member

⭐ Suggestion

For any given lib option {lib}, eg dom or es2019, we should look up a module @typescript/lib{lib} (eg, @typescript/libdom or @typescript/libes2019) for the library file before falling back to loading the lib file bundled with the compiler. This will allow users to bring their own lib copies by overriding or redirecting this package to their own versions of it, and offload version conflict checking to package managers.

📃 Motivating Example

In #44795 we express a desire to override the builtin dom with another version of the dom lib. This would allow us to do so. Specifically, if we load @typescript/libdom for the dom .d.ts files, you could make your package.json look like this:

{
  "dependencies": {
    "@types/web": "*",
    "@typescript/libdom": "node_modules/@types/web"
  }
}

we'd then find the @types/web declaration files (linked) in the @typescript/libdom folder, and load them as the canonical dom lib. The package manager can then take care of version conflicts between custom dom versions (obviously only one top-level @typescript/libdom folder can be installed!) and handle redirects for us.

cc @orta @andrewbranch

@andrewbranch andrewbranch added In Discussion Not yet reached consensus Suggestion An idea for TypeScript labels Sep 1, 2021
@orta
Copy link
Contributor

orta commented Sep 2, 2021

Yeah, confirmed that this works and to be honest - it feels like the best answer to me.

I believe this is probably the most reliable setup for it across all package managers:

{
  "dependencies": {
    "@typescript/libdom": "npm:@types/web"
  }
}

@andrewbranch
Copy link
Member

TIL that npm: syntax

@weswigham
Copy link
Member Author

There's also file: and git: that I know of. You can also point it directly at a tarball of a package and it usually just works. It's pretty flexible.

@orta
Copy link
Contributor

orta commented Sep 2, 2021

One thing I'm trying to think about is what this could look like with respect to #43972

I think my current plan is to separate out dom.globals.d.ts and dom.types.d.ts in such a way that dom.d.ts just imports both (for apps) but that something like node can write /// <reference lib="dom.types"> (for libs)

Do you think then that would resolve to /node_modules/@typescript/libdom/types.d.ts or /node_modules/@typescript/libdom-types/index.d.ts ?

@weswigham
Copy link
Member Author

I'm thinking the later. Separate packages for each referencable lib we add so you can override/fallback each one individually.

@orta
Copy link
Contributor

orta commented Sep 3, 2021

Hrm, is both a plausible answer also?

Today @types/web ships with dom.d.ts and dom.iterable.d.ts for convince - if we split types out from globals to allow node etc to reuse them then it's quite reasonable for the pkg to end up hosting: dom.d.ts, dom.iterable.d.ts, dom.types.d.tsanddom.globals.d.ts`

If they were one per packages you'd need to do:

 "dependencies": {
    "@typescript/libdom": "npm:@types/web-dom",
    "@typescript/libdom-iterable": "npm:@types/web-dom-iterable",
    "@typescript/libdom-global": "npm:@types/web-dom-global",
    "@typescript/libdom-types": "npm:@types/web-dom-types",
  }

Which would probably be a bit of an overkill, but if we supported internal routing at the .

 "dependencies": {
    "@typescript/libdom": "npm:@types/web-dom"
  }

turning into:

  • /// <reference lib="dom"> -> @types/web-dom/index.d.ts
  • /// <reference lib="dom.types"> -> @types/web-dom/types.d.ts
  • /// <reference lib="dom.globals"> -> @types/web-dom/globals.d.ts
  • /// <reference lib="dom.iterable"> -> @types/web-dom/iterable.d.ts

@orta
Copy link
Contributor

orta commented Sep 17, 2021

Implemented in #45771

@kettanaito
Copy link

Glad to see this feature implemented!

May we have an example please of how to override types from lib.dom.d.ts from a local .d.ts file?

I'd like to ship a types package that makes MessageChannel support generics for outgoing/incoming events, making the entire messaging type-safe. How would I approach this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants