TypeScriptを使用してangular 2アプリ用のサービスを作成しています。このサービスは、ChromeのServiceWorker
を使用してプッシュ通知をリッスンします( チュートリアル を参照)。 )。コード(javascript)は、最初にnavigator
を使用して、serviceWorker
がサポートされているかどうかを確認してから、登録などを完了し続けます。
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);
});
}
TypeScriptを使用して上記を実装したいと思います。ただし、TypeScriptコンパイラ(以下を参照)で使用されている現在のlib.d.ts
には、Navigator
またはserviceWorker.register
などの関連メソッドのserviceWorker
で定義された定義がないようです。 (これはクロム固有の実装なので、私は推測します)。
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;
}
その結果、コンパイラは関連するserviceWorker
型を見つけることができないため、コンパイルエラーに直面します。私はJavaScriptとTypeScriptに慣れていないので、続行するための最良の方法を決定しようとしています。私は次のような選択肢を理解しています。
serviceWorker
が定義されている既存のTypeScript定義ライブラリを見つけて、コンパイル時に含めます。lib.d.ts
を何らかの方法で拡張します。最良の選択肢に関する賢人のアドバイスは大歓迎です。
更新
コンパイルエラーを削除するためにanyにキャストしようとしました。
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);
});
しかし、今は新しいエラーに直面しています。
error TS7006: Parameter 'reg' implicitly has an 'any' type.
error TS7006: Parameter 'error' implicitly has an 'any' type.
また、これらを使用してServiceWorkerの定義を書きたくなりました details 。ただし、これまでに行ったことがないので、練習が必要です。
ServiceWorker and friends の型定義が DefinitelyTyped/service_worker_api から利用できるようになりました:
$ typings install dt~service_worker_api --global --save
service_worker_api
└── (No dependencies)
使用例:
// 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/' });
}
}
必要に応じてパスを調整します。
元の回答
WebStormで使用するために作成したタイピングは次のとおりです: 要点 。
次に、service-worker.tsファイルに参照を含めます:/// <reference path="YOUR_PATH_HERE/service-worker.d.ts" />
。
それに応じてパスを調整するか、グローバルにすると、かなり設定されているはずです。かなり完成していますが、いくつか欠けているものがあると思います。とにかく、これがお役に立てば幸いです。
2018更新:
Lib.webworker.d.tsをes5 +ライブラリ(lib.es5.d.ts、lib.es2015.d.tsなど)と一緒に使用できるように、これらの定義の新しいエディションをここで公開しました: Service Worker補足lib.webworker.d.ts への入力。このセットは、今日、はるかに関連性が高いはずです。
TypeScriptファイルのインターフェースに追加することができ、lib.d.tsが更新されると、コンパイラーはそれが不要になったと通知します。
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) { }
);
または
定義を変更する代わりに、任意のパラメータを使用してany
オブジェクトに呼び出しをキャストできます。
var n = <any>navigator;
n.getUserMedia = n.getUserMedia || n.webkitGetUserMedia || n.mozGetUserMedia || n.msGetUserMedia;
return n.getUserMedia({video: true, audio:true}, onSuccess, onFail);
ServiceWorkerはchrome特定の拡張機能ではありません。
OPは、人気のあるブラウザでのServiceWorkerの現在の状態の概要について、Jake Archibaldの isSERVICEWORKERready? ページを参照する必要があります。
OPによるインターフェース情報 リンク に基づいてtsd.d.ts
に型定義を追加しましたが、機能しているようです。
注意してくださいangular.d.ts からIPromise
インターフェースを参照しました。
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;
}
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.');
}
}
Chromeでのアプリのビルドと読み込み
次のコンソールメッセージをログに記録します。
お役に立てれば。