繁体   English   中英

TypeScript ServiceWorker 的类型定义

[英]TypeScript type definitions for ServiceWorker

我正在使用 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或其相关方法(如 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 的现有serviceWorker定义库,并在编译期间包含它。
  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 编写定义。 但是以前从未做过,所以需要一些练习!

现在可以从DefinitelyTyped / service_worker_api获得ServiceWorker和朋友的类型定义:

$ 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一起使用的打字: Gist

然后在我的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 Typings to Supplement 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) {  }
);

要么

您可以使用arbitray参数调用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应该参考Jake Archibald的isSERVICEWORKERready? 有关流行浏览器中ServiceWorker当前状态的详细信息页面。

我根据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中构建和加载应用程序

在此输入图像描述

记录以下控制台消息:

在此输入图像描述

希望这可以帮助。

您现在可以直接在 javascript 中为 Service Worker 使用类型,而无需安装额外的包:

// @ts-check
/// <reference no-default-lib="true"/>
/// <reference lib="webworker" />
(
  /** @param worker {ServiceWorkerGlobalScope} */
  (worker) => {


    worker.addEventListener('install', (event) => {
      // ...
    });


})(/** @type {any} */(self) );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM