-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Unable to access ServiceWorkerGlobalScope via self.
#14877
Comments
I have not found references in the sepec that I think declare var clients: Clients; |
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. |
|
I'm wondering whether we need to separate typings of web worker and service worker for the following reasons:
|
FYI #11781 |
As a workaround I am currently doing this (function (self: ServiceWorkerGlobalScope) {
//Service worker contents...
})(<ServiceWorkerGlobalScope>self); Anyone have a better solution? |
Any progress about this? It's kinda sad that we cannot use Service Workers alongside Type Script. |
I did this: const { clients, addEventListener, skipWaiting, registration } = self as ServiceWorkerGlobalScope; Note you need "webworker" lib with 2.4 |
Adding |
@abarisain I came up with your solution as well but it fails with following error
How did you configure your tsconfig.json to have it working? Thanks! The workaround I found was:
...but you then have to use |
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. Here is what works for me:
here is my tsconfig
(the extend part is irrelevant, as all options defined in my base tsconfig are for other stuff) |
Thanks for your very fast answer :) I was stucked with 2.3.4 for other parts of the project but switching to 2.5.2 did not solve my compile error. I am always very confused with the triple-slash thing... and how it relates to adding libs in tsconfig.json
Nevermind, I will remain with my trick... it does the job as well... Hopefully, I will eventually understand those nasty typing issues... not speaking about how to tell the IDE that this file/folder is a service worker while the rest is in the context of |
The triple slashes are exactly how I tell that a file is a service worker :) it overrides every "lib" entry, but it's quite a dirty hack. |
Here is what worked for me:
{
"compilerOptions": {
"lib": [
"es6",
"webworker",
"dom"
]
}
}
import { } from ".";
declare var self: ServiceWorkerGlobalScope; Not sure why the empty import is required 🤷♂️ |
I assume to mark file as a module. Without import/export statements TS doesn't mark file as a module. |
@Tetr4 using an empty import caused an error for me:
Adding |
@Tetr4 I got errors using your approach as I then got duplicated references between I ended up having to build a referenced tsconfig.json with two library configs (kind of like this), which seemed to work ok, but then with So, I still have some configuration issue, but I'm pretty close. |
I'm having related issues with this.
https://github.com/wilsonpage/vscode-scope-test-case |
Piecing together several comments in here, this is all I ended up needing:
I found multiple config files and installing npm packages not necessary (or even helpful). |
|
The workaround described in this issue doesn't appear to work anymore in TypeScript 4.1 because it actually puts the |
In TypeScript 4.1+ it seems you can still get it working if you something like this /// <reference lib="webworker" />
//@ts-ignore
sw=self;
declare var sw: ServiceWorkerGlobalScope; at the top of your file, and then use |
With TypeScript 4.3, I now have the following: /// <reference no-default-lib="true"/>
/// <reference lib="es2020" />
/// <reference lib="WebWorker" />
const sw = self as ServiceWorkerGlobalScope & typeof globalThis The |
@Tetr4 Thanks a lot, that fixed it for me but no need to import with |
Using the lib Triple-Slash Directive and no-default-lib Triple-Slash Directive
However, if I use these directives in my webworker's source file, other files in my project (and inside node_modules) choke because they can no longer find the DOM stuff (Window, HTMLCollection, document, etc...) The docs say:
Looks like using these directives is global, therefore pretty much equivalent to setting Related: Possible solution: https://joshuatz.com/posts/2021/strongly-typed-service-workers/#solution-b-tsconfig-libs |
Here is a good workaround, with sw.ts /// <reference lib="webworker" />
declare const self: ServiceWorkerGlobalScope |
Does anybody have a JS only solution (jsdoc syntax)? I got as far as: /// <reference lib="WebWorker" />
/** @type {ServiceWorkerGlobalScope} */
const context = /** @type {unknown} */ (self); But I'd have to change all references to /// <reference no-default-lib="true"/>
/// <reference lib="WebWorker" />
/** @type {ServiceWorkerGlobalScope} */
const self = globalThis.self; Would yield If I try just importing the the lib, It can't find it: /** @type {import('typescript/lib/lib.webworker').ServiceWorkerGlobalScope} */
const self = globalThis.self;
|
@clshortfuse JSDoc isn't related to TypeScript and isn't Microsoft's responsibility. |
@soryy708 You're mistaken. Typescript supports either TS files or JSDocs syntax. In fact, it's part of the official proposal. https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html |
Rewrote the Service Worker in TypeScript! It *kind of* works great, but not quite. I wish the TypeScript team made tooling for Workers a bit better, as it seems harder to work with than it should be. This rewrite was all from last night, and it took a few hours to learn how to get things right (I didn't get around to commiting it until now though). There aren't any type errors anymore, but I'm also unsure if it will run sucessfully yet. I don't have a device/OS to test the Web Share Target API support anymore, since my Chromebook runs Ubuntu now :) While it's not fully functional yet, this is a step in the right direction for type-safe Service Worker code! I mostly rewrote it with my new programming styles, expanding things out for readability, and making use of async-await where it was previously just `.then()` calls and such. Some help to get it working: https://github.com/NicholasPeretti/service-worker-ts-example https://stackoverflow.com/questions/89332/how-do-i-recover-a-dropped-stash-in-git (I had an oopsie XD) Edit: Tried testing out the worker in the browser, and modern TypeScript now includes empty `export {}` instances in the resulting JS, which breaks declaring the file as a module, as you can't have `export {}` in a non-module script. The only way I got close to this was to name the file `.mts`, but I'm not sure if I like that or not. But hey, it may work. With that being a possible solution, I found all of these sources along the way also: https://stackoverflow.com/questions/56356655/structuring-a-typescript-project-with-workers https://github.com/jakearchibald/typescript-worker-example (now outdated, unfortunately, thanks to this new TypeScript change) microsoft/TypeScript#41513 https://www.devextent.com/create-service-worker-typescript/ (almost works! falls down to the same issue sadly) microsoft/TypeScript#14877 microsoft/TypeScript#11781
This CL does a couple of things: 1. Moves the worker script into its own ts_library because it needs a different tsconfig.json than the rest of the code. Ideally we would be able to use the same target for both, but declarations in the lib.webworker.d.ts conflict with lib.dom.d.ts. See microsoft/TypeScript#20595 2. The tsconfig.json needs 'webworker' for web worker APIs. 3. In the worker script, add an empty export so we can re-declare `self` and re-declare `self` as SharedWorkerGlobalScope so we can use shared worker APIs. See microsoft/TypeScript#14877 4. Fixes shared worker creation to work with trusted types. We loose some type safety when we create the worker because lib.dom.d.ts doesn't support Trusted Types yet. See microsoft/TypeScript#30024 5. Random fixes for the linter and typescript compilation. Change-Id: I1d21e67f58b5f3d6b879c21af9e18c18aa6025fd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4289336 Reviewed-by: Zain Afzal <[email protected]> Commit-Queue: Giovanni Ortuno Urquidi <[email protected]> Cr-Commit-Position: refs/heads/main@{#1110774}
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. /* eslint-env serviceworker */
/// <reference lib="webworker" />
const self = /** @type {ServiceWorkerGlobalScope} */(/** @type {unknown} */(globalThis.self)) |
I newer TS version we are still not allowed to redeclare self. |
My current favorite workaround: (function (this: ServiceWorkerGlobalScope) {
this.addEventListener('install', async (event) => {
await this.skipWaiting();
// ...
});
}).call(self); |
after adding bun-types to qwik project, this hint helped me. |
Cannot find name 'ServiceWorkerGlobalScope'.ts(2304) |
I really like that library, but I think I only want to use in in places I fully have to. Now that my Service Worker is implemented in full plain TS, rather than JSDoc JS, I can use the plain standard library types again. It's still not as simple as just using a plain `<reference>` directive, but all of the types are indeed right! microsoft/TypeScript#14877 https://github.com/BenjaminAster/Better-TypeScript
The answer from @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() |
Since
ServiceWorker
related types sit inlib.webworker.d.ts
,webworker
lib need to be added totsconfig.json
.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.
The text was updated successfully, but these errors were encountered: