web-dev-qa-db-ja.com

ServiceWorkerのTypeScriptタイプ定義

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に慣れていないので、続行するための最良の方法を決定しようとしています。私は次のような選択肢を理解しています。

  1. Jsコードを保持し、コンパイルエラーを単に無視します(理想的ではありません)。
  2. Jsコードを保持し、コンパイル中の型エラーをなんとかして抑制します。
  3. serviceWorkerが定義されている既存のTypeScript定義ライブラリを見つけて、コンパイル時に含めます。
  4. ナビゲーター用に独自の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 。ただし、これまでに行ったことがないので、練習が必要です。

8
James B

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/' });
    }
}

必要に応じてパスを調整します。

6

元の回答

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 への入力。このセットは、今日、はるかに関連性が高いはずです。

2
tiernanx

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);
1

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でのアプリのビルドと読み込み

enter image description here

次のコンソールメッセージをログに記録します。

enter image description here

お役に立てれば。

1
Sourav Paul