Repository navigation
Unable to access ServiceWorkerGlobalScope via self. #14877
Description
Activity
I have not found references in the sepec that
selfis of typeServiceWorkerGlobalScope.I think
clientsshould be available as a global variable though. i.e.:declare var clients: Clients;
Reacted by Vytenis, Brandon Bennett, Mikhail Isaev aka iMike, Chesnokov Artemii and FunctionPointReacted by Steven CochraneReacted by Edixon Piña- addedBugA bug in TypeScriptA bug in TypeScriptDomain: lib.d.tsThe issue relates to the different libraries shipped with TypeScriptThe issue relates to the different libraries shipped with TypeScriptHelp WantedYou can do thisYou can do this
on Mar 27, 2017 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.
YuichiNukiyama commented
on Apr 1, 2017 ContributorMore actionsselfproperty will return browsing context object. And according to MDN, sometimes returnServiceWorkerGlobalScopeobject. See following docs.Reacted by Hossam El-Deen and BryanI'm wondering whether we need to separate typings of web worker and service worker for the following reasons:
- If we put all worker typings into one lib, How can we prevent web worker user using service worker methods and properties like
clients. closeis not accessible in service worker, how can we omitcloseinServiceWorderGlobalScope?- We can access service worker methods and properties like
clientsregistrationviaselfin Chrome 57.(Just like theselfin Window)
Reacted by Jakub Korzeniowski, Soroush, Cédric Belin, Brandon Bennett and Timothy Totten- If we put all worker typings into one lib, How can we prevent web worker user using service worker methods and properties like
YuichiNukiyama commented
on Apr 6, 2017 ContributorMore actionsFYI #11781
As a workaround I am currently doing this
(function (self: ServiceWorkerGlobalScope) { //Service worker contents... })(<ServiceWorkerGlobalScope>self);
Anyone have a better solution?
Reacted by Nikolai Orekhov, Nicolas HENRY, blindbox, Miya, Sora2455, ExE Boss, JAAvander, BlackGlory, liamkernighan, Richard Wilburn and 4 moreAny progress about this? It's kinda sad that we cannot use Service Workers alongside Type Script.
Reacted by syuilo, Jakub Korzeniowski, Ryan Blackman, Andrii Kharsun, Simon Reinisch, KajMagnus, Doug Hoskisson, Emmie Päivärinta, Brandon Bennett, dominictobias and 3 moreI did this:
const { clients, addEventListener, skipWaiting, registration } = self as ServiceWorkerGlobalScope;
Note you need "webworker" lib with 2.4
Reacted by William JohnsonReacted by Steven CochraneAdding
declare var self: ServiceWorkerGlobalScope;on top of my service worker implementation fixes thatReacted by Hossam El-Deen, Marius Volkhart, Peter Radocchia, electrovir, Fabrizio Duroni, Edgar, Emmie Päivärinta, Noah-Jerome Lotzer, hanshou101, Kostiantyn Levytskyi and 28 moreReacted by Steven Cochrane and SovLynReacted by hanshou101Reacted by hanshou101Reacted by hanshou101Reacted by hanshou101, Kostiantyn Levytskyi and Yoomin KangReacted by hanshou101Arnaud 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
_selfeverywhere :(Reacted by Paul Young, Stanislav Panchenko, technatoria, Charles Crossan and SovLynReacted by Taka OkunishiAre 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.tshas some other patches to fix the incomplete definitionshere 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)
Reacted by shishir arora22 remaining items
- added a commit that references this issue
on Oct 15, 2022 - added a commit that references this issue
on Feb 28, 2023 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))
Reacted by Piotr KulaReacted by Matthiasconst 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.Reacted by FalcoMy current favorite workaround:
(function (this: ServiceWorkerGlobalScope) { this.addEventListener('install', async (event) => { await this.skipWaiting(); // ... }); }).call(self);
Reacted by Carlos Lopez, Karol Majewski and FalcoUsing the lib Triple-Slash Directive
/// <reference lib="WebWorker" />makesServiceWorkerGlobalScopeavailableafter adding bun-types to qwik project,
ServiceWorkerGlobalScope type lost it's reference and result in TS compile error.this hint helped me.
Reacted by Brandon Blakeley, Yosafat Kesuma, Dan Nisenson and Rorydeclare var self: ServiceWorkerGlobalScope;
Cannot find name 'ServiceWorkerGlobalScope'.ts(2304)
type ServiceWorkerGlobalScope =/unresolved/ any- added a commit that references this issue
on Jan 22, 2024 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);
I used this without modifying tsconfig:
/// <reference lib="webworker" /> function main() { const { clients, addEventListener, skipWaiting } = self as unknown as ServiceWorkerGlobalScope } main()
Reacted by Falco, Ben Jones and Amish Kumar NaiduI'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 libDOMandtsconfig.json'sjsxmode. 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
webworkercontext for the subset.Reacted by Lachlan Heywood and FalcoReacted by Lachlan Heywoodsaschanaz commented
on Jun 8, 2025 ContributorMore actionsmicrosoft/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.
Reacted by Jake Archibald and FalcoReacted by Sirz Benjiemicrosoft/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=serviceworkerdoes not seem to be supported. What on earth is webworker if not service worker?lib=serviceworkerdoes 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 workersSo not every Worker has the Same GlobalScope and so they need different Types to access different APIs.
Reacted by GabenGar and Marcin Wiśniowski

Since
ServiceWorkerrelated types sit inlib.webworker.d.ts,webworkerlib need to be added totsconfig.json.{ "compilerOptions": { "lib": [ "es2017", "webworker" ] } }But in current
lib.webworker.d.ts, itdeclare var self: WorkerGlobalScope;, so we can't access ServiceWorkerGlobalScope viaself.TypeScript Version: 2.2.1
Expected behavior:
Can access ServiceWorkerGlobalScope via
self.(likeself.clients)Actual behavior:
Access with error.