Skip to content

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

Closed

Description

⭐ 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 Therox (@orta) Andrew Branch (@andrewbranch)

Activity

  1. orta commented on Sep 2, 2021

    @orta
    Contributor

    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"
      }
    }
  2. andrewbranch commented on Sep 2, 2021

    @andrewbranch
    Member

    TIL that npm: syntax

  3. weswigham commented on Sep 2, 2021

    @weswigham
    MemberAuthor

    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.

  4. orta commented on Sep 2, 2021

    @orta
    Contributor

    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 ?

  5. weswigham commented on Sep 2, 2021

    @weswigham
    MemberAuthor

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

  6. orta commented on Sep 3, 2021

    @orta
    Contributor

    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
  7. orta commented on Sep 17, 2021

    @orta
    Contributor

    Implemented in #45771

  8. kettanaito commented on Oct 3, 2022

    @kettanaito

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    In DiscussionNot yet reached consensusSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions