TypeScript type definitions for ServiceWorker
Solution 1
Type definitions for ServiceWorker and friends are now available from DefinitelyTyped/service_worker_api:
$ typings install dt~service_worker_api --global --save
service_worker_api
└── (No dependencies)
Usage example:
// data-access.service.ts
/// <reference path="typings/globals/service_worker_api/index.d.ts" />
import { Injectable } from '@angular/core';
@Injectable()
export class DataAccess {
constructor() {
navigator.serviceWorker.register('service-worker.js', { scope: '/api/' });
}
}
Adjust the paths as necessary.
Solution 2
ServiceWorker is not a chrome specific extension.
OP should refer to Jake Archibald's isSERVICEWORKERready? page for a rundown of the current state of ServiceWorker in the popular browsers.
I added the type definitions in tsd.d.ts
based on the interface information linked by OP and they seem to be working.
Please note that I referenced IPromise
interface from angular.d.ts.
Defined in tsd.d.ts
/// <reference path="angularjs/angular.d.ts" />
interface Navigator {
serviceWorker: ServiceWorkerContainer;
}
interface ServiceWorkerContainer {
register(scriptUrl: string, options?: RegistrationOptions): angular.IPromise<ServiceWorkerRegistration>;
}
interface RegistrationOptions {
scope: string;
}
interface ServiceWorkerRegistration {
installing?: ServiceWorker;
waiting?: ServiceWorker;
active?: ServiceWorker;
scope: string;
update(): angular.IPromise<void>;
unregister(): angular.IPromise<boolean>;
}
interface ServiceWorker {
scriptUrl: string;
state: string;
postMessage(message: any, transfer: Array<any>): void;
}
Referred in home-controller.ts
///<reference path='../../typings/tsd.d.ts' />
...
// dependencies are injected via AngularJS $injector
constructor() {
var vm = this;
vm.ctrlName = 'HomeCtrl';
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js', { scope: '/' }).then(function(reg) {
// registration worked
console.log('Registration succeeded. Scope is ' + reg.scope);
}).catch(function(error) {
// registration failed
console.log('Registration failed with ' + error);
});
} else {
console.warn('serviceWorker not available in navigator.');
}
}
Building and loading the app in the chrome
logs the following console message:
Hope this helps.
Solution 3
You can add to the interface in your TypeScript file and when the lib.d.ts is updated, the compiler will tell you that you no longer need it.
interface Navigator {
getUserMedia(
options: { video?: bool; audio?: bool; },
success: (stream: any) => void,
error?: (error: string) => void
) : void;
}
navigator.getUserMedia(
{video: true, audio: true},
function (stream) { },
function (error) { }
);
or
Instead of changing the definition you can cast to an any
object an call with arbitray parameters e.g:
var n = <any>navigator;
n.getUserMedia = n.getUserMedia || n.webkitGetUserMedia || n.mozGetUserMedia || n.msGetUserMedia;
return n.getUserMedia({video: true, audio:true}, onSuccess, onFail);
Solution 4
Original Answer
Here are the Typings I created to use with WebStorm: Gist.
Then in my service-worker.ts file I include a reference: /// <reference path="YOUR_PATH_HERE/service-worker.d.ts" />
.
Adjust your path accordingly, or make them global and you should be pretty set. It's fairly complete, but I'm sure it's missing some things. Anyway, I hope this helps.
2018 Update:
I published a new edition of these definitions to work with lib.webworker.d.ts along with any es5+ library (lib.es5.d.ts, lib.es2015.d.ts, etc) here: Service Worker Typings to Supplement lib.webworker.d.ts. This set should be much more relevant today.
James B
Updated on July 19, 2022Comments
-
James B almost 2 years
I'm writing a service for my angular 2 app using TypeScript. The service makes use of chrome's
ServiceWorker
to listen for push notifications (see tutorial). The code (javascript) makes use ofnavigator
first to see ifserviceWorker
is supported, then continues to complete registration etc., i.e.,if ('serviceWorker' in navigator) { console.log('Service Worker is supported'); navigator.serviceWorker.register('sw.js').then(function() { return navigator.serviceWorker.ready; }).then(function(reg) { console.log('Service Worker is ready :^)', reg); // TODO }).catch(function(error) { console.log('Service Worker error :^(', error); }); }
I'd like to implemenet the above using TypeScript. However, the current
lib.d.ts
used by the TypeScript compiler (see below) appears to have no definitions defined onNavigator
for theserviceWorker
or its associated methods such asserviceWorker.register
(I guess since it's a chrome-specific implementation).interface Navigator extends Object, NavigatorID, NavigatorOnLine, NavigatorContentUtils, NavigatorStorageUtils, NavigatorGeolocation, MSNavigatorDoNotTrack, MSFileSaver, NavigatorUserMedia { readonly appCodeName: string; readonly cookieEnabled: boolean; readonly language: string; readonly maxTouchPoints: number; readonly mimeTypes: MimeTypeArray; readonly msManipulationViewsEnabled: boolean; readonly msMaxTouchPoints: number; readonly msPointerEnabled: boolean; readonly plugins: PluginArray; readonly pointerEnabled: boolean; readonly webdriver: boolean; getGamepads(): Gamepad[]; javaEnabled(): boolean; msLaunchUri(uri: string, successCallback?: MSLaunchUriCallback, noHandlerCallback?: MSLaunchUriCallback): void; requestMediaKeySystemAccess(keySystem: string, supportedConfigurations: MediaKeySystemConfiguration[]): PromiseLike<MediaKeySystemAccess>; vibrate(pattern: number | number[]): boolean; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; }
The result is that I'm faced with compilation errors since the compiler can't find the associated
serviceWorker
types. Given I'm new to JavaScript and TypeScript, I'm trying to determine the best way to proceed. I understand the options to be:- Keep the js code and simply ignore the compilation errors (not ideal).
- Keep the js code and somehow suppress the type errors during compilation.
- Find an existing typescript definitions library that
has
serviceWorker
defined and include that during compilation. - Write my own typescript definition file for navigator or somehow
extend the existing
lib.d.ts
Sage advice on the best option greatly appreciated.
Update
Attempted to cast to any to remove compilation errors, i.e.,
var nav = <any> navigator; if ('serviceWorker' in nav) { nav.serviceWorker.register('sw.js') .then(function(reg) { console.log('yey!', <any> reg); }).catch(function(err) { console.log('boo!', <any> err); });
but now facing new errors, i.e.,
error TS7006: Parameter 'reg' implicitly has an 'any' type. error TS7006: Parameter 'error' implicitly has an 'any' type.
Also, tempted to write definitions for the ServiceWorker using these details. However never done it before, so will need some practice!