ServiceWorker 的 TypeScript 类型定义

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38172450/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:37:08  来源:igfitidea点击:

TypeScript type definitions for ServiceWorker

javascripttypescriptangularservice-worker

提问by James B

I'm writing a service for my angular 2 app using TypeScript. The service makes use of chrome's ServiceWorkerto listen for push notifications (see tutorial). The code (javascript) makes use of navigatorfirst to see if serviceWorkeris supported, then continues to complete registration etc., i.e.,

我正在使用 TypeScript 为我的 angular 2 应用程序编写服务。该服务使用 chromeServiceWorker来侦听推送通知(请参阅教程)。代码(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);
  });
}

I'd like to implemenet the above using TypeScript. However, the current lib.d.tsused by the TypeScript compiler (see below) appears to have no definitions defined on Navigatorfor the serviceWorkeror its associated methods such as serviceWorker.register(I guess since it's a chrome-specific implementation).

我想使用 TypeScript 实现上述内容。但是,lib.d.tsTypeScript 编译器使用的当前版本(见下文)似乎没有NavigatorserviceWorker或其相关方法定义定义,例如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;
}

The result is that I'm faced with compilation errors since the compiler can't find the associated serviceWorkertypes. Given I'm new to JavaScript and TypeScript, I'm trying to determine the best way to proceed. I understand the options to be:

结果是我面临编译错误,因为编译器找不到关联的serviceWorker类型。鉴于我是 JavaScript 和 TypeScript 的新手,我正在尝试确定继续进行的最佳方式。我理解的选项是:

  1. Keep the js code and simply ignore the compilation errors (not ideal).
  2. Keep the js code and somehow suppress the type errors during compilation.
  3. Find an existing typescript definitions library that has serviceWorkerdefined and include that during compilation.
  4. Write my own typescript definition file for navigator or somehow extend the existing lib.d.ts
  1. 保留 js 代码并简单地忽略编译错误(不理想)。
  2. 保留 js 代码并在编译期间以某种方式抑制类型错误。
  3. 查找已serviceWorker在编译期间定义并包含的现有打字稿定义库。
  4. 为导航器编写我自己的打字稿定义文件或以某种方式扩展现有的 lib.d.ts

Sage advice on the best option greatly appreciated.

非常感谢圣人关于最佳选择的建议。

Update

更新

Attempted to cast to any to remove compilation errors, i.e.,

尝试强制转换为 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);
    });

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!

此外,还想使用这些细节为 ServiceWorker 编写定义。但是以前从来没有做过,所以需要一些练习!

回答by Maxim Egorushkin

Type definitions for ServiceWorker and friendsare now available from DefinitelyTyped/service_worker_api:

ServiceWorker 和朋友的类型定义现在可以从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.

根据需要调整路径。

回答by tiernanx

Original Answer

原答案

Here are the Typings I created to use with WebStorm: Gist.

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

Then in my service-worker.ts file I include a reference: /// <reference path="YOUR_PATH_HERE/service-worker.d.ts" />.

然后在我的 service-worker.ts 文件中包含一个引用:/// <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:

2018 更新:

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.

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

回答by AngJobs on Github

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.

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

or

或者

Instead of changing the definition you can cast to an anyobject an call with arbitray parameters e.g:

您可以将any具有任意参数的调用转换为对象,而不是更改定义,例如:

 var n = <any>navigator;
    n.getUserMedia  = n.getUserMedia || n.webkitGetUserMedia || n.mozGetUserMedia || n.msGetUserMedia;
    return  n.getUserMedia({video: true, audio:true}, onSuccess, onFail);

回答by Sourav Paul

ServiceWorker is not a chrome specific extension.

ServiceWorker 不是 chrome 特定的扩展。

OP should refer to Jake Archibald's isSERVICEWORKERready?page for a rundown of the current state of ServiceWorker in the popular browsers.

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

I added the type definitions in tsd.d.tsbased on the interface information linkedby OP and they seem to be working.

tsd.d.ts根据OP链接的接口信息添加了类型定义,它们似乎正在工作。

Please notethat I referenced IPromiseinterface from angular.d.ts.

请注意,我IPromiseangular.d.ts引用了接口。

Defined in tsd.d.ts

定义于 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

参考文献 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

在 chrome 中构建和加载应用程序

enter image description here

在此处输入图片说明

logs the following console message:

记录以下控制台消息:

enter image description here

在此处输入图片说明

Hope this helps.

希望这可以帮助。