[Web API type definition issue] Mark navigator.serviceWorker as an optional property
Summary
navigator.serviceWorker may be undefined in some secure contexts, like IABs and Firefox Private Mode
Expected vs. Actual Behavior
navigator.serviceWorker.register()
Expected: throw a TypeScript error; serviceWorker may be undefined
Actual: no TypeScript error
Playground Link
No response
Browser Support
- [x] This API is supported in at least two major browser engines (not two Chromium-based browsers).
Have Tried The Latest Releases
- [x] This issue applies to the latest release of TypeScript.
- [x] This issue applies to the latest release of
@types/web.
Additional Context
I am requesting a reconsideration of marking navigator.serviceWorker as optional.
The previous issue opened in 2023 on the TypeScript repository has been labeled as "Working as Intended" under the explanation by Ryan Cavanaugh: (https://github.com/microsoft/TypeScript/issues/52044#issuecomment-1372844081)
Quoting:
APIs like these are marked non-optional for convenience, since it's extremely plausible that your script runs only in secure contexts as an invariant.
Based on his comment, it appears to me that it had been misunderstood that serviceWorker is undefined in non-secure contexts, while the point is that it may be undefined even in secure contexts.
Examples include but are not limited to:
- Firefox's private mode
- Some in-app browsers, especially those on iOS.
In-app browser usage is not insignificant!
~62% of global web traffic comes from mobile devices, and, according to eMarketer, ~88% of the time people spend in their mobile devices is used on apps. Apps today incorporate IABs for the purposes of authentication, advertisement, and more. IAB usage is at its peak in social media and messaging apps.
Given the high usage of IABs. serviceWorker not being an optional property of navigator is anything but convenient.
Hello @stavros-tsioulis This is intentional. There are a lot of calls like this that only work in a secure context. If you know your code is always going to run over HTTPS, it would be incredibly annoying and counterproductive if the compiler forced you do either do a null check or add a non-null assertion to every such call.
Hi there @Bashamega .
I am always assuming code to be running over HTTPS. However, even so, it is still not true that serviceWorker is defined in all secure contexts!
For example, here is the page on MDN falsely claiming that navigator.serviceWorker is available so long as window.isSecureContext is true.
Try to open firefox on a private window and you'll find out that window.isSecureContext is true, while navigator.serviceWorker is undefined.
The same is true for certain IABs used on apps like Messenger.
Contradictorily to the previous MDN page, the one for navigator.serviceWorker clarifies that this feature may not be available in some secure contexts.
Basically: navigator.serviceWorker may be undefined over HTTPS. There are secure contexts where this property is undefined, which are not so rare or niche where convenience of non-optionality is a better option.
Hello @stavros-tsioulis In this case, it is better to file an issue upstream in MDN. Once that issue is resolved, it should automatically reflect here.
Thanks @Bashamega Could you perhaps help me pinpoint what part in MDN should be changed?
I am not sure @stavros-tsioulis Maybe @saschanaz can help
First of all, what is IAB?
Firefox not providing Service Worker in PBM is not a feature but rather a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1320796
Making this optional will disturb a lot of codes where the existence of service worker can be safely assumed, so this library doesn't make it optional unless the spec says so.
Hi @saschanaz IAB stands for in-app browser. If the typings of this API are to fully reflect the spec, there is probably nothing more to discuss here.
I also stumbled upon https://caniwebview.com/search/?s=serviceWorker which reveals a much wider range of APIs, especially those connected to navigator, that are unavailable on various WebViews. I can see how it would be untenable to maintain overrides based simply on arbitrary decisions of implementers to deactivate such APIs, against the spec.
Perhaps there can be separate libs for webviews.
I really miss the conditional compilation (but only for type libs), it could save a lot of complexity here, where the users would be able to just compile with webview requirement. 🥺