【问题标题】:TypeScript type definitions for ServiceWorkerServiceWorker 的 TypeScript 类型定义
【发布时间】:2016-07-03 17:20:02
【问题描述】:

我正在使用 TypeScript 为我的 angular 2 应用程序编写服务。该服务使用 chrome 的 ServiceWorker 来监听推送通知(参见 tutorial)。代码(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 或其相关方法(例如serviceWorker.register)定义定义(我猜是因为它是特定于chrome 的实现)。

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 并在编译期间包含它。
  4. 为导航器或以某种方式编写我自己的打字稿定义文件 扩展现有的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.

此外,很想使用这些details 为 ServiceWorker 编写定义。但是以前从未做过,所以需要一些练习!

【问题讨论】:

    标签: javascript typescript angular service-worker


    【解决方案1】:

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

    根据需要调整路径。

    【讨论】:

    • 从 TypeScript 2.0 开始,npm install --save @types/service_worker_apiwill also work
    • @mjs 这是一个非常好的改进。
    • 链接已失效。请更新您的答案,谢谢!
    【解决方案2】:

    您可以在 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);
    

    【讨论】:

    • 强制转换是最简单的解决方案,但是尝试强制转换为&lt;any&gt; 会出现错误TS7006: Parameter 'reg' implicitly has an 'any' type。 - 查看更新。
    【解决方案3】:

    ServiceWorker 不是特定于 chrome 的扩展。

    OP 应该参考 Jake Archibald 的 isSERVICEWORKERready? 页面,了解流行浏览器中 ServiceWorker 的当前状态。

    我根据 OP 的接口信息linkedtsd.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 中构建和加载应用程序

    记录以下控制台消息:

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      原答案

      以下是我创建的用于 WebStorm 的类型:Gist

      然后在我的 service-worker.ts 文件中包含一个参考:/// &lt;reference path="YOUR_PATH_HERE/service-worker.d.ts" /&gt;

      相应地调整您的路径,或将它们设为全局,您应该已经准备好了。它相当完整,但我敢肯定它缺少一些东西。无论如何,我希望这会有所帮助。

      2018 年更新:

      我在此处发布了这些定义的新版本以与 lib.webworker.d.ts 以及任何 es5+ 库(lib.es5.d.ts、lib.es2015.d.ts 等)一起使用:Service Worker Typings to Supplement lib.webworker.d.ts .这组在今天应该更有意义。

      【讨论】:

      猜你喜欢
      • 2016-06-22
      • 1970-01-01
      • 2017-12-21
      • 2019-04-01
      • 2017-08-23
      • 2020-11-11
      • 2016-12-02
      • 2017-11-24
      • 2017-07-13
      相关资源
      最近更新 更多