jsr icon indicating copy to clipboard operation
jsr copied to clipboard

Support modifying global types

Open koddsson opened this issue 1 year ago • 7 comments

I'm not sure where this error is coming from. Is it from jsr or TypeScript or somewhere else? How can I fix it?

Example run here: https://github.com/koddsson/context-protocol/actions/runs/8480796983/job/23237140188

koddsson avatar Mar 29 '24 12:03 koddsson

This is coming from JSR. JSR does not currently allow global declarations. See https://jsr.io/docs/about-slow-types#global-augmentation.

cc @dsherret - we should consider allowing global declarations in entrypoints maybe.

lucacasonato avatar Apr 01 '24 10:04 lucacasonato

Cheers 🙏🏻

Not sure how I can use JSR for this specific package (and probably others) as I often need to let TypeScript know of some globals like Web Components created and new events that will fire.

Another good example would be something like this: https://github.com/github/tab-container-element/blob/21f1e2b8dcc43d7905dbe806e508ea6e510e0d9e/src/tab-container-element-define.ts#L18-L24

koddsson avatar Apr 02 '24 10:04 koddsson

Global augmentation is really useful. It could provide types for injects. In a meta-framework, like in cordis, it using declare module for very cool injects. You can achieve this:

declare module 'cordis' { // declare the types for `kv_store`
  kv_store: MyStore
}

class MyStore extends cordis.Service {
  constructor(ctx: cordis.Context, options: {}) {
    super(ctx, 'kv_store') // inject as `kv_store` in Context
  }

  get(/*...*/) { /*...*/ }
  set(/*...*/) { /*...*/ }
}

function main() {
  const ctx = new cordis.Context()
  const scope = ctx.plugin(MyStore, { ... }) // installs the plugin
  ctx.inject(['kv_store'], (ctx) => { // kv_store now available under the Context
    // you can now easily use `kv_store` without coupling, 
    // the underlying implementation can be easily changed to anything with same interface.
    // hmr in backends could also be possible with cordis.
    ctx.kv_store.set("foo", "bar")  
    ctx.kv_store.get("foo") === "bar";
    scope.dispose() // dispose all side-effect of the plugin (also unregisters the inject)
    typeof ctx.get('kv_store') === "undefined" // `kv_store` is gone
  })
}

You can inject a kv_store into Context, and other plugins could simply use it with ctx.kv_store. And declaring declare module make TypeScript to work with injects.

Other plugins could import type {} from 'kv_store', and get the types working. If no declare module, it will resulting Property 'kv_store' not available in type 'Context'. And that will make the development process extremely uncomfortable.

CyanChanges avatar Dec 04 '24 15:12 CyanChanges

Linking the issue from the Deno repo here: https://github.com/denoland/deno/issues/23427

kanashimia avatar Dec 15 '24 15:12 kanashimia

Please considerate this as an option, I can't publish my library on JSR only for this error.

eythaann avatar Dec 18 '24 16:12 eythaann

jsx namesapce also needs this option, i can not publish https://github.com/ije/html to jsr.io, help 🙏

error: Failed to publish @ije/[email protected]

Caused by:
    Failed to publish @ije/html at 0.3.0: modifying global types is not allowed file:///jsx.ts:36:1

ije avatar Mar 03 '25 01:03 ije