Skip to content

Unable to access ServiceWorkerGlobalScope via self. #14877

Description

Since ServiceWorker related types sit in lib.webworker.d.ts, webworker lib need to be added to tsconfig.json.

{
  "compilerOptions": {
    "lib": [
      "es2017",
      "webworker"
    ]
  }
}

But in current lib.webworker.d.ts, it declare var self: WorkerGlobalScope;, so we can't access ServiceWorkerGlobalScope via self.


TypeScript Version: 2.2.1

Expected behavior:

Can access ServiceWorkerGlobalScope via self.(like self.clients)

Actual behavior:

Access with error.

image

Activity

  1. mhegazy commented on Mar 27, 2017

    @mhegazy
    Contributor

    I have not found references in the sepec that self is of type ServiceWorkerGlobalScope.

    I think clients should be available as a global variable though. i.e.:

    declare var clients: Clients;
  2. mhegazy commented on Mar 27, 2017

    @mhegazy
    Contributor

    PRs welcomed. You can find more information about contributing lib.d.ts fixes at https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md#contributing-libdts-fixes.

  3. YuichiNukiyama commented on Apr 1, 2017

    @YuichiNukiyama
    Contributor

    self property will return browsing context object. And according to MDN, sometimes return ServiceWorkerGlobalScope object. See following docs.

  4. vincentbel commented on Apr 3, 2017

    @vincentbel
    Author

    I'm wondering whether we need to separate typings of web worker and service worker for the following reasons:

    1. If we put all worker typings into one lib, How can we prevent web worker user using service worker methods and properties like clients.
    2. close is not accessible in service worker, how can we omit close in ServiceWorderGlobalScope?
    3. We can access service worker methods and properties like clients registration via self in Chrome 57.(Just like the self in Window)

    image

  5. YuichiNukiyama commented on Apr 6, 2017

    @YuichiNukiyama
    Contributor

    FYI #11781

  6. robianmcd commented on May 2, 2017

    @robianmcd

    As a workaround I am currently doing this

    (function (self: ServiceWorkerGlobalScope) {
       //Service worker contents...
    })(<ServiceWorkerGlobalScope>self);

    Anyone have a better solution?

  7. Havret commented on Jun 2, 2017

    @Havret

    Any progress about this? It's kinda sad that we cannot use Service Workers alongside Type Script.

  8. mohsen1 commented on Jun 28, 2017

    @mohsen1
    Contributor

    I did this:

    const { clients, addEventListener, skipWaiting, registration } = self as ServiceWorkerGlobalScope;

    Note you need "webworker" lib with 2.4

  9. abarisain commented on Sep 2, 2017

    @abarisain

    Adding declare var self: ServiceWorkerGlobalScope; on top of my service worker implementation fixes that

  10. added this to the milestone on Sep 5, 2017
  11. jandsu commented on Sep 29, 2017

    @jandsu

    Arnaud Barisain-Monrose (@abarisain) I came up with your solution as well but it fails with following error

    Variable 'self' must be of type 'WorkerGlobalScope', but here has type 'ServiceWorkerGlobalScope'.
    

    How did you configure your tsconfig.json to have it working? Thanks!

    The workaround I found was:

    const _self = self as ServiceWorkerGlobalScope;
    

    ...but you then have to use _self everywhere :(

  12. abarisain commented on Sep 29, 2017

    @abarisain

    Are you using the latest typescript version?

    Turns out since I commented, my needs evolved: I needed to define new variables on the global scope.
    Since my project mixes a lot of environments, I also had to have many sub .tsconfig files.

    Here is what works for me:

    /// <reference path='../../../node_modules/typescript/lib/lib.es6.d.ts' />
    /// <reference path='../../../node_modules/typescript/lib/lib.webworker.d.ts' />
    /// <reference path="../../types/contextual/serviceworker-patches.d.ts" />
    
    import { foo } from './bar'
    declare var self: MyWorkerGlobalScope;
    interface MyWorkerGlobalScope extends ServiceWorkerGlobalScope {
      handleForwardedEvent?: (eventName: string, event: Event) => Promise<void>;
    }
    

    serviceworker-patches.d.ts has some other patches to fix the incomplete definitions

    here is my tsconfig

    {
      "extends": "../tsconfig.json",
      "compilerOptions": {
        "lib": ["es6"]
      }
    }
    

    (the extend part is irrelevant, as all options defined in my base tsconfig are for other stuff)

  13. 22 remaining items

  14. falco467 commented on Mar 10, 2023

    @falco467

    Carlos Lopez (@clshortfuse)

    We need to cast to unknown first, to remove the error about incompatible types. It is not very pretty, but at least just two lines overall.
    This seems to work today without any errors and full Intellisense:

    /* eslint-env serviceworker */
    /// <reference lib="webworker" />
    const self = /** @type {ServiceWorkerGlobalScope} */(/** @type {unknown} */(globalThis.self))
  15. madsskoett commented on Aug 22, 2023

    @madsskoett
    const self = /** @type {ServiceWorkerGlobalScope} */(/** @type {unknown} */(globalThis.self))

    I newer TS version we are still not allowed to redeclare self.
    My workaround is: const redeclaredSelf = (self as unknown as ServiceWorkerGlobalScope);
    and then using "redeclaredSelf" instead of self.

  16. jordaaash commented on Sep 3, 2023

    @jordaaash

    My current favorite workaround:

    (function (this: ServiceWorkerGlobalScope) {
        this.addEventListener('install', async (event) => {
            await this.skipWaiting();
            // ...
        });
    }).call(self);
  17. xaverine commented on Sep 28, 2023

    @xaverine

    Using the lib Triple-Slash Directive /// <reference lib="WebWorker" /> makes ServiceWorkerGlobalScope available

    after adding bun-types to qwik project,
    ServiceWorkerGlobalScope type lost it's reference and result in TS compile error.

    this hint helped me.

  18. thanhtutzaw commented on Sep 30, 2023

    @thanhtutzaw

    declare var self: ServiceWorkerGlobalScope;

    Cannot find name 'ServiceWorkerGlobalScope'.ts(2304)
    type ServiceWorkerGlobalScope =/unresolved/ any

  19. mikehutter commented on Nov 22, 2024

    @mikehutter

    The answer from Jordan (@jordaaash) was close for me, but I had to tweak it using Pick because I was still getting "not assignable" errors going from WorkerGlobalScope to ServiceWorkerGlobalScope.

    (function (this: Pick<ServiceWorkerGlobalScope, "addEventListener">) {
        this.addEventListener('install', async (event) => {
            await this.skipWaiting();
            // ...
        });
    }).call(self);
  20. risenxxx commented on Jan 3, 2025

    @risenxxx

    I used this without modifying tsconfig:

    /// <reference lib="webworker" />
    
    function main() {
      const { clients, addEventListener, skipWaiting } =
        self as unknown as ServiceWorkerGlobalScope
    }
    
    main()
  21. rajsite commented on Apr 30, 2025

    @rajsite

    I'm using the WebAssembly jco tools and the JS runtime it uses supports fetch-event.

    So not quite a service worker runtime but follows the same API surface for addEventListener('fetch'). Unfortunately, using /// <reference lib="webworker" /> caused type conflicts with lib DOM and tsconfig.json's jsx mode. Instead I ended up manually defining the type on global:

    // Manually define FetchEvent types based on:
    // https://github.com/microsoft/TypeScript/blob/v5.8.3/src/lib/webworker.generated.d.ts#L2956
    
    declare global {
      interface WindowEventMap {
        fetch: FetchEvent;
      }
    }
    
    interface FetchEvent extends Event {
      readonly request: Request;
      respondWith(r: Response | PromiseLike<Response>): void;
    }
    
    addEventListener('fetch', e => e.respondWith(myHandler(e.request)));

    Would be nice if types like these were more piecemeal and re-composable to avoid referencing the whole webworker context for the subset.

  22. saschanaz commented on Jun 8, 2025

    @saschanaz
    Contributor

    microsoft/TypeScript-DOM-lib-generator#1498 won't really fix this, the core issue here is that lib=serviceworker should be used instead of webworker.

    And with that I think this can be closed.

  23. SirzBenjie commented on Aug 25, 2025

    @SirzBenjie

    microsoft/TypeScript-DOM-lib-generator#1498 won't really fix this, the core issue here is that lib=serviceworker should be used instead of webworker.

    And with that I think this can be closed.

    lib=serviceworker does not seem to be supported. What on earth is webworker if not service worker?

  24. falco467 commented on Sep 16, 2025

    @falco467

    Sirz Benjie (@SirzBenjie)

    lib=serviceworker does not seem to be supported. What on earth is webworker if not service worker?

    Quoting MDN:

    Service workers are a type of web worker.

    While Window is not directly available to workers, many of the same methods are defined in a shared mixin (WindowOrWorkerGlobalScope), and made available to workers through their own WorkerGlobalScope-derived contexts:

    DedicatedWorkerGlobalScope for dedicated workers
    SharedWorkerGlobalScope for shared workers
    ServiceWorkerGlobalScope for service workers

    So not every Worker has the Same GlobalScope and so they need different Types to access different APIs.

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

    BugA bug in TypeScriptDomain: lib.d.tsThe issue relates to the different libraries shipped with TypeScriptHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions