ServiceWorker的TypeScript类型定义

Jam*_*s B 7 javascript typescript service-worker angular

我正在使用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);
  });
}
Run Code Online (Sandbox Code Playgroud)

我想使用TypeScript实现上述功能.但是,目前lib.d.ts所用的打字稿编译器(见下文)似乎对定义没有定义NavigatorserviceWorker或与其相关的方法,如serviceWorker.register(我猜的,因为它是一个特定的铬实现).

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;
}
Run Code Online (Sandbox Code Playgroud)

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

  1. 保留js代码并简单地忽略编译错误(不理想).
  2. 保留js代码并以某种方式抑制编译期间的类型错误.
  3. 查找已serviceWorker定义的现有typescript定义库,并在编译期间包含该库.
  4. 为导航器编写我自己的打字稿定义文件或以某种方式扩展现有的 lib.d.ts

关于最佳选择的Sage建议非常感谢.

更新

试图强制转换为删除编译错误,即

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);
    });
Run Code Online (Sandbox Code Playgroud)

但现在面临新的错误,即

error TS7006: Parameter 'reg' implicitly has an 'any' type.
error TS7006: Parameter 'error' implicitly has an 'any' type.
Run Code Online (Sandbox Code Playgroud)

此外,还试图使用这些详细信息为ServiceWorker编写定义.但是从来没有做过,所以需要一些练习!

Max*_*kin 6

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

$ typings install dt~service_worker_api --global --save
service_worker_api
??? (No dependencies)
Run Code Online (Sandbox Code Playgroud)

用法示例:

// 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/' });
    }
}
Run Code Online (Sandbox Code Playgroud)

根据需要调整路径.

  • 从 TypeScript 2.0 开始,`npm install --save @types/service_worker_api` [也可以使用](https://blogs.msdn.microsoft.com/typescript/2016/06/15/the-future-of-declaration-文件/)。 (5认同)

Ang*_*hub 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) {  }
);
Run Code Online (Sandbox Code Playgroud)

或者

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

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